Java源码示例:org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder
示例1
/**
* Create a signer that wraps {@code os} and generates a detached signature using
* {@code signingKey}. After closing, you should call {@link #getSignature()} to get the detached
* signature.
*
* @param os is the upstream {@link OutputStream} which is not closed by this object
* @throws RuntimeException to rethrow {@link PGPException}
*/
public RydePgpSigningOutputStream(
@WillNotClose OutputStream os,
PGPKeyPair signingKey) {
super("RydePgpSigningOutputStream", os, false);
try {
signer = new PGPSignatureGenerator(
new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256));
signer.init(BINARY_DOCUMENT, signingKey.getPrivateKey());
} catch (PGPException e) {
throw new RuntimeException(e);
}
addUserInfoToSignature(signingKey.getPublicKey(), signer);
}
示例2
@Test
public void testSignVerify_Detached() throws Exception {
// Load the keys.
PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY);
PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY);
PGPPublicKey publicKey = publicKeyRing.getPublicKey();
PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey());
// Sign the data and write signature data to "signatureFile".
// Note: RSA_GENERAL will encrypt AND sign. RSA_SIGN and RSA_ENCRYPT are deprecated.
PGPSignatureGenerator signer = new PGPSignatureGenerator(
new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256));
signer.init(PGPSignature.BINARY_DOCUMENT, privateKey);
addUserInfoToSignature(publicKey, signer);
signer.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
ByteArrayOutputStream output = new ByteArrayOutputStream();
signer.generate().encode(output);
byte[] signatureFileData = output.toByteArray();
logger.atInfo().log(".sig file data: %s", dumpHex(signatureFileData));
// Load algorithm information and signature data from "signatureFileData".
PGPSignature sig;
try (ByteArrayInputStream input = new ByteArrayInputStream(signatureFileData)) {
PGPObjectFactory pgpFact = new BcPGPObjectFactory(input);
PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
assertThat(sigList.size()).isEqualTo(1);
sig = sigList.get(0);
}
// Use "onePass" and "sig" to verify "publicKey" signed the text.
sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
sig.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
assertThat(sig.verify()).isTrue();
// Verify that they DIDN'T sign the text "hello monster".
sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
sig.update("hello monster".getBytes(UTF_8));
assertThat(sig.verify()).isFalse();
}
示例3
protected void testInit () throws IOException
{
if ( this.initialized )
{
return;
}
this.initialized = true;
try
{
this.signatureGenerator = new PGPSignatureGenerator ( new BcPGPContentSignerBuilder ( this.privateKey.getPublicKeyPacket ().getAlgorithm (), this.digestAlgorithm ) );
this.signatureGenerator.init ( PGPSignature.BINARY_DOCUMENT, this.privateKey );
this.armoredOutput = new ArmoredOutputStream ( this.stream );
if ( this.version != null )
{
this.armoredOutput.setHeader ( "Version", this.version );
}
if ( this.inline )
{
this.armoredOutput.beginClearText ( this.digestAlgorithm );
}
}
catch ( final PGPException e )
{
throw new IOException ( e );
}
}
示例4
@Override
public void feedHeader ( final ByteBuffer header )
{
try
{
final BcPGPContentSignerBuilder contentSignerBuilder = new BcPGPContentSignerBuilder ( this.privateKey.getPublicKeyPacket ().getAlgorithm (), this.hashAlgorithm );
final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator ( contentSignerBuilder );
signatureGenerator.init ( PGPSignature.BINARY_DOCUMENT, this.privateKey );
if ( header.hasArray () )
{
signatureGenerator.update ( header.array (), header.position (), header.remaining () );
}
else
{
final byte[] buffer = new byte[header.remaining ()];
header.get ( buffer );
signatureGenerator.update ( buffer );
}
this.value = signatureGenerator.generate ().getEncoded ();
logger.info ( "RSA HEADER: {}", this.value );
}
catch ( final Exception e )
{
throw new RuntimeException ( e );
}
}
示例5
@Override
public Key createNewKey(CreateKeyParams params) throws FieldValidationException {
try {
Preconditions.checkArgument(params != null, "params must not be null");
assertParamsValid(params);
// Create Master key
KeyPair masterKey = getOrGenerateKeyPair(getMasterKeyParameters());
PGPKeyPair masterKeyBc = new JcaPGPKeyPair(algorithmNameToTag(masterKeyPurpose), masterKey, new Date());
BcPGPContentSignerBuilder keySignerBuilderBc = new BcPGPContentSignerBuilder(
algorithmNameToTag(masterKeyPurpose), hashAlgorithmNameToTag(masterKeySignerHashingAlgorithm));
// Setup seret key encryption
PGPDigestCalculator digestCalc = new BcPGPDigestCalculatorProvider()
.get(hashAlgorithmNameToTag(secretKeyHashingAlgorithm));
BcPBESecretKeyEncryptorBuilder encryptorBuilderBC = new BcPBESecretKeyEncryptorBuilder(
symmetricKeyAlgorithmNameToTag(secretKeyEncryptionAlgorithm), digestCalc);
PBESecretKeyEncryptor keyEncryptorBc = encryptorBuilderBC.build(params.getPassphrase().toCharArray());
// Key pair generator
String userName = params.getFullName() + " <" + params.getEmail() + ">";
PGPKeyRingGenerator keyPairGeneratorBc = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
masterKeyBc, userName, digestCalc, null, null, keySignerBuilderBc, keyEncryptorBc);
// Add Sub-key for encryption
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(encryptionKeyAlgorithm, PROVIDER);
if ("ELGAMAL".equals(encryptionKeyAlgorithm)) {
keyPairGenerator.initialize(new DHParameterSpec(dhParamsPrimeModulus, dhParamsBaseGenerator));
} else if ("RSA".equals(encryptionKeyAlgorithm)) {
// Re-using master key size.
keyPairGenerator.initialize(new RSAKeyGenParameterSpec(masterKeySize, RSAKeyGenParameterSpec.F4));
} else {
throw new IllegalArgumentException(
"Hanlding of parameter creation for " + encryptionKeyAlgorithm + " is not implemented");
}
KeyPair encryptionSubKey = keyPairGenerator.generateKeyPair();
PGPKeyPair encryptionSubKeyBc = new JcaPGPKeyPair(algorithmNameToTag(encryptionKeyPurpose),
encryptionSubKey, new Date());
keyPairGeneratorBc.addSubKey(encryptionSubKeyBc);
// TBD-191: Also add a sub-key for signing
// KeyPair signatureSubKey = keyPairGenerator.generateKeyPair();
// PGPKeyPair signatureSubKeyBc = new
// TBD-191: RSA_SIGN must not be hardcoded
// JcaPGPKeyPair(algorithmNameToTag("RSA_SIGN"), signatureSubKey,
// new Date());
// keyPairGeneratorBc.addSubKey(signatureSubKeyBc);
// building ret
return buildKey(keyPairGeneratorBc);
} catch (Throwable t) {
Throwables.throwIfInstanceOf(t, FieldValidationException.class);
throw new RuntimeException("Failed to generate key", t);
}
}
示例6
/**
* Builds a PGPContentSignerBuilder for the specified algorithms.
*/
protected PGPContentSignerBuilder buildSignerBuilder(int keyAlgorithm, int hashAlgorithm) {
return new BcPGPContentSignerBuilder(keyAlgorithm, hashAlgorithm);
}
示例7
private static PGPKeyRingGenerator generateKeyRingGenerator( String id, char[] pass, int s2kcount, int keySize,
KeyPair keyPair ) throws PGPException
{
// This object generates individual key-pairs.
RSAKeyPairGenerator kpg = new RSAKeyPairGenerator();
// Boilerplate RSA parameters, no need to change anything
// except for the RSA key-size (2048). You can use whatever
// key-size makes sense for you -- 4096, etc.
kpg.init( new RSAKeyGenerationParameters( BigInteger.valueOf( 0x10001 ), new SecureRandom(), keySize, 12 ) );
// First create the master (signing) key with the generator.
PGPKeyPair rsakp_sign = new BcPGPKeyPair( PGPPublicKey.RSA_GENERAL, kpg.generateKeyPair(), new Date() );
// Then an encryption subkey.
PGPKeyPair rsakp_enc = new BcPGPKeyPair( PGPPublicKey.RSA_GENERAL, kpg.generateKeyPair(), new Date() );
keyPair.setPrimaryKeyId( Long.toHexString( rsakp_sign.getKeyID() ) );
keyPair.setPrimaryKeyFingerprint( BytesToHex( rsakp_sign.getPublicKey().getFingerprint() ) );
keyPair.setSubKeyId( Long.toHexString( rsakp_enc.getKeyID() ) );
keyPair.setSubKeyFingerprint( BytesToHex( rsakp_enc.getPublicKey().getFingerprint() ) );
// Add a self-signature on the id
PGPSignatureSubpacketGenerator signhashgen = new PGPSignatureSubpacketGenerator();
// Add signed metadata on the signature.
// 1) Declare its purpose
signhashgen.setKeyFlags( false, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER );
// 2) Set preferences for secondary crypto algorithms to use
// when sending messages to this key.
signhashgen.setPreferredSymmetricAlgorithms( false, new int[] {
SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128,
SymmetricKeyAlgorithmTags.CAST5, SymmetricKeyAlgorithmTags.TRIPLE_DES
} );
signhashgen.setPreferredHashAlgorithms( false, new int[] {
HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512,
HashAlgorithmTags.SHA224,
} );
signhashgen.setPreferredCompressionAlgorithms( false, new int[] {
CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZIP
} );
// 3) Request senders add additional checksums to the
// message (useful when verifying unsigned messages.)
signhashgen.setFeature( false, Features.FEATURE_MODIFICATION_DETECTION );
// Create a signature on the encryption subkey.
PGPSignatureSubpacketGenerator enchashgen = new PGPSignatureSubpacketGenerator();
// Add metadata to declare its purpose
enchashgen.setKeyFlags( false, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE );
// Objects used to encrypt the secret key.
PGPDigestCalculator sha1Calc = new BcPGPDigestCalculatorProvider().get( HashAlgorithmTags.SHA1 );
// bcpg 1.48 exposes this API that includes s2kcount. Earlier
// versions use a default of 0x60.
PBESecretKeyEncryptor pske =
( new BcPBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc, s2kcount ) ).build( pass );
// Finally, create the keyring itself. The constructor
// takes parameters that allow it to generate the self
// signature.
PGPKeyRingGenerator keyRingGen =
new PGPKeyRingGenerator( PGPSignature.POSITIVE_CERTIFICATION, rsakp_sign, id, sha1Calc,
signhashgen.generate(), null,
new BcPGPContentSignerBuilder( rsakp_sign.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA1 ), pske );
// Add our encryption subkey, together with its signature.
keyRingGen.addSubKey( rsakp_enc, enchashgen.generate(), null );
return keyRingGen;
}
示例8
@Override
public void sign ( final InputStream in, final OutputStream out, final boolean inline ) throws Exception
{
final int digest = HashAlgorithmTags.SHA1;
final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator ( new BcPGPContentSignerBuilder ( this.privateKey.getPublicKeyPacket ().getAlgorithm (), digest ) );
if ( inline )
{
signatureGenerator.init ( PGPSignature.CANONICAL_TEXT_DOCUMENT, this.privateKey );
}
else
{
signatureGenerator.init ( PGPSignature.BINARY_DOCUMENT, this.privateKey );
}
final ArmoredOutputStream armoredOutput = new ArmoredOutputStream ( out );
armoredOutput.setHeader ( "Version", VersionInformation.VERSIONED_PRODUCT );
if ( inline )
{
armoredOutput.beginClearText ( digest );
final LineNumberReader lnr = new LineNumberReader ( new InputStreamReader ( in, StandardCharsets.UTF_8 ) );
String line;
while ( ( line = lnr.readLine () ) != null )
{
if ( lnr.getLineNumber () > 1 )
{
signatureGenerator.update ( NL_DATA );
}
final byte[] data = trimTrailing ( line ).getBytes ( StandardCharsets.UTF_8 );
if ( inline )
{
armoredOutput.write ( data );
armoredOutput.write ( NL_DATA );
}
signatureGenerator.update ( data );
}
armoredOutput.endClearText ();
}
else
{
final byte[] buffer = new byte[4096];
int rc;
while ( ( rc = in.read ( buffer ) ) >= 0 )
{
signatureGenerator.update ( buffer, 0, rc );
}
}
final PGPSignature signature = signatureGenerator.generate ();
signature.encode ( new BCPGOutputStream ( armoredOutput ) );
armoredOutput.close ();
}
示例9
/**
* Encrypt, sign and write input stream data to output stream.
* Input and output stream are closed.
*/
private static void encryptAndSign(
InputStream plainInput, OutputStream encryptedOutput,
PersonalKey myKey, List<PGPUtils.PGPCoderKey> receiverKeys)
throws IOException, PGPException {
// setup data encryptor & generator
BcPGPDataEncryptorBuilder encryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_192);
encryptor.setWithIntegrityPacket(true);
encryptor.setSecureRandom(new SecureRandom());
// add public key recipients
PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encryptor);
receiverKeys.forEach(key ->
encGen.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(key.encryptKey)));
OutputStream encryptedOut = encGen.open(encryptedOutput, new byte[BUFFER_SIZE]);
// setup compressed data generator
PGPCompressedDataGenerator compGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
OutputStream compressedOut = compGen.open(encryptedOut, new byte[BUFFER_SIZE]);
// setup signature generator
int algo = myKey.getSigningAlgorithm();
PGPSignatureGenerator sigGen = new PGPSignatureGenerator(
new BcPGPContentSignerBuilder(algo, HashAlgorithmTags.SHA256));
sigGen.init(PGPSignature.BINARY_DOCUMENT, myKey.getPrivateSigningKey());
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false, myKey.getUserId());
sigGen.setUnhashedSubpackets(spGen.generate());
sigGen.generateOnePassVersion(false).encode(compressedOut);
// Initialize literal data generator
PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator();
OutputStream literalOut = literalGen.open(
compressedOut,
PGPLiteralData.BINARY,
"",
new Date(),
new byte[BUFFER_SIZE]);
// read the "in" stream, compress, encrypt and write to the "out" stream
// this must be done if clear data is bigger than the buffer size
// but there are other ways to optimize...
byte[] buf = new byte[BUFFER_SIZE];
int len;
while ((len = plainInput.read(buf)) > 0) {
literalOut.write(buf, 0, len);
sigGen.update(buf, 0, len);
}
literalGen.close();
// generate the signature, compress, encrypt and write to the "out" stream
sigGen.generate().encode(compressedOut);
compGen.close();
encGen.close();
}
示例10
@Test
public void testSignVerify_OnePass() throws Exception {
// Load the keys.
PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY);
PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY);
PGPPublicKey publicKey = publicKeyRing.getPublicKey();
PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey());
// Sign the data and write signature data to "signatureFile".
PGPSignatureGenerator signer = new PGPSignatureGenerator(
new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256));
signer.init(PGPSignature.BINARY_DOCUMENT, privateKey);
addUserInfoToSignature(publicKey, signer);
ByteArrayOutputStream output = new ByteArrayOutputStream();
signer.generateOnePassVersion(false).encode(output);
signer.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
signer.generate().encode(output);
byte[] signatureFileData = output.toByteArray();
logger.atInfo().log(".sig file data: %s", dumpHex(signatureFileData));
// Load algorithm information and signature data from "signatureFileData".
PGPSignature sig;
PGPOnePassSignature onePass;
try (ByteArrayInputStream input = new ByteArrayInputStream(signatureFileData)) {
PGPObjectFactory pgpFact = new BcPGPObjectFactory(input);
PGPOnePassSignatureList onePassList = (PGPOnePassSignatureList) pgpFact.nextObject();
PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject();
assertThat(onePassList.size()).isEqualTo(1);
assertThat(sigList.size()).isEqualTo(1);
onePass = onePassList.get(0);
sig = sigList.get(0);
}
// Use "onePass" and "sig" to verify "publicKey" signed the text.
onePass.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
onePass.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8));
assertThat(onePass.verify(sig)).isTrue();
// Verify that they DIDN'T sign the text "hello monster".
onePass.init(new BcPGPContentVerifierBuilderProvider(), publicKey);
onePass.update("hello monster".getBytes(UTF_8));
assertThat(onePass.verify(sig)).isFalse();
}