internal SecretKeyPacket( BcpgInputStream bcpgIn) { pubKeyPacket = new PublicKeyPacket(bcpgIn); s2kUsage = bcpgIn.ReadByte(); if (s2kUsage == UsageChecksum || s2kUsage == UsageSha1) { encAlgorithm = (SymmetricKeyAlgorithmTag) bcpgIn.ReadByte(); s2k = new S2k(bcpgIn); } else { encAlgorithm = (SymmetricKeyAlgorithmTag) s2kUsage; } if (!(s2k != null && s2k.Type == S2k.GnuDummyS2K && s2k.ProtectionMode == 0x01)) { if (s2kUsage != 0) { if (((int) encAlgorithm) < 7) { iv = new byte[8]; } else { iv = new byte[16]; } bcpgIn.ReadFully(iv); } } secKeyData = bcpgIn.ReadAll(); }
/// <summary>Existing SecureRandom constructor.</summary> /// <param name="encAlgorithm">The symmetric algorithm to use.</param> /// <param name="rand">Source of randomness.</param> public PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag encAlgorithm, SecureRandom rand) { this.defAlgorithm = encAlgorithm; this.rand = rand; }
/// <summary> /// Initializes a new instance of the <see cref="SymmetricKeyEncSessionPacket"/> class. /// </summary> /// <param name="encAlgorithm">The enc algorithm.</param> /// <param name="s2k">The S2K.</param> /// <param name="secKeyData">The sec key data.</param> public SymmetricKeyEncSessionPacket(SymmetricKeyAlgorithmTag encAlgorithm, S2k s2k, byte[] secKeyData) { this.Version = 4; this.EncAlgorithm = encAlgorithm; this.S2K = s2k; this._secKeyData = secKeyData; }
/// <summary> /// Initializes a new instance of the <see cref="ECDHPublicKeyParameters" /> class. /// </summary> /// <param name="q">The q.</param> /// <param name="parameters">The parameters.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> public ECDHPublicKeyParameters(ECPoint q, ECDomainParameters parameters, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : base("ECDH", q, parameters) { this.HashAlgorithm = hashAlgorithm; this.SymmetricKeyAlgorithm = symmetricKeyAlgorithm; }
/// <summary> /// Initializes a new instance of the <see cref="ECDHPublicKeyParameters" /> class. /// </summary> /// <param name="q">The q.</param> /// <param name="publicKeyParamSet">The public key param set.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> public ECDHPublicKeyParameters(ECPoint q, DerObjectIdentifier publicKeyParamSet, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : base("ECDH", q, publicKeyParamSet) { this.HashAlgorithm = hashAlgorithm; this.SymmetricKeyAlgorithm = symmetricKeyAlgorithm; }
/// <summary> /// Initializes a new instance of the <see cref="ECKeyGenerationParameters"/> class. /// </summary> /// <param name="publicKeyParamSet">The public key param set.</param> /// <param name="random">The random.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> public ECKeyGenerationParameters(DerObjectIdentifier publicKeyParamSet, ISecureRandom random, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : this(ECKeyParameters.LookupParameters(publicKeyParamSet), random) { _publicKeyParamSet = publicKeyParamSet; _hashAlgorithm = hashAlgorithm; _symmetricKeyAlgorithm = symmetricKeyAlgorithm; }
/// <summary> /// Initializes a new instance of the <see cref="ECKeyGenerationParameters"/> class. /// </summary> /// <param name="domainParameters">The domain parameters.</param> /// <param name="random">The random.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> public ECKeyGenerationParameters(ECDomainParameters domainParameters, ISecureRandom random, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : base(random, domainParameters.N.BitLength) { _domainParams = domainParameters; _hashAlgorithm = hashAlgorithm; _symmetricKeyAlgorithm = symmetricKeyAlgorithm; }
public PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag encAlgorithm, bool withIntegrityPacket) { this.defAlgorithm = encAlgorithm; this.withIntegrityPacket = withIntegrityPacket; this.rand = new SecureRandom(); }
/// <summary> /// Creates a ECDH public key parameters from the given encoded point. /// </summary> /// <param name="encodedPoint">The encoded point.</param> /// <param name="publicKeyParamSet">The public key param set.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> /// <returns></returns> public static ECDHPublicKeyParameters Create(IBigInteger encodedPoint, DerObjectIdentifier publicKeyParamSet, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) { var curve = ECKeyPairGenerator.FindECCurveByOid(publicKeyParamSet); var point = curve.Curve.DecodePoint(encodedPoint.ToByteArrayUnsigned()); return new ECDHPublicKeyParameters(point, publicKeyParamSet, hashAlgorithm, symmetricKeyAlgorithm); }
internal PbeMethod( SymmetricKeyAlgorithmTag encAlgorithm, S2k s2k, KeyParameter key) { this.encAlgorithm = encAlgorithm; this.s2k = s2k; this.key = key; }
/// <summary>Base constructor.</summary> /// <param name="encAlgorithm">The symmetric algorithm to use.</param> /// <param name="rand">Source of randomness.</param> /// <param name="oldFormat">PGP 2.6.x compatibility required.</param> public PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag encAlgorithm, SecureRandom rand, bool oldFormat) { this.defAlgorithm = encAlgorithm; this.rand = rand; this.oldFormat = oldFormat; }
/// <summary> /// Initializes a new instance of the <see cref="SecretKeyPacket"/> class. /// </summary> /// <param name="pubKeyPacket">The pub key packet.</param> /// <param name="encAlgorithm">The enc algorithm.</param> /// <param name="s2KUsage">The s2 K usage.</param> /// <param name="s2K">The s2 K.</param> /// <param name="iv">The iv.</param> /// <param name="secKeyData">The sec key data.</param> public SecretKeyPacket(IPublicKeyPacket pubKeyPacket, SymmetricKeyAlgorithmTag encAlgorithm, int s2KUsage, S2k s2K, byte[] iv, byte[] secKeyData) { this.PublicKeyPacket = pubKeyPacket; this.EncAlgorithm = encAlgorithm; this.S2KUsage = s2KUsage; this.S2K = s2K; _iv = Arrays.Clone(iv); _secKeyData = secKeyData; }
public SecretSubkeyPacket( PublicKeyPacket pubKeyPacket, SymmetricKeyAlgorithmTag encAlgorithm, S2k s2k, byte[] iv, byte[] secKeyData) : base(pubKeyPacket, encAlgorithm, s2k, iv, secKeyData) { }
internal PgpSecretKey( PgpPrivateKey privKey, PgpPublicKey pubKey, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSha1, SecureRandom rand) : this(privKey, pubKey, encAlgorithm, passPhrase, useSha1, rand, false) { }
public SymmetricKeyEncSessionPacket( BcpgInputStream bcpgIn) { version = bcpgIn.ReadByte(); encAlgorithm = (SymmetricKeyAlgorithmTag) bcpgIn.ReadByte(); s2k = new S2k(bcpgIn); secKeyData = bcpgIn.ReadAll(); }
/// <summary> /// Initializes a new instance of the <see cref="SecretKeyPacket"/> class. /// </summary> /// <param name="pubKeyPacket">The pub key packet.</param> /// <param name="encAlgorithm">The enc algorithm.</param> /// <param name="s2K">The s2 K.</param> /// <param name="iv">The iv.</param> /// <param name="secKeyData">The sec key data.</param> public SecretKeyPacket(IPublicKeyPacket pubKeyPacket, SymmetricKeyAlgorithmTag encAlgorithm, S2k s2K, byte[] iv, byte[] secKeyData) { this.PublicKeyPacket = pubKeyPacket; this.EncAlgorithm = encAlgorithm; this.S2KUsage = encAlgorithm != SymmetricKeyAlgorithmTag.Null ? UsageChecksum : UsageNone; this.S2K = s2K; _iv = Arrays.Clone(iv); _secKeyData = secKeyData; }
/// <summary> /// Initializes a new instance of the <see cref="ECDHPublicBcpgKey"/> class. /// </summary> /// <param name="point">The point.</param> /// <param name="oid">The oid.</param> /// <param name="hashAlgorithm">The hash algorithm.</param> /// <param name="symmetricKeyAlgorithm">The symmetric key algorithm.</param> public ECDHPublicBcpgKey(ECPoint point, DerObjectIdentifier oid, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : base(point, oid) { _reserved = 1; _hashFunctionId = (byte)hashAlgorithm; _symAlgorithmId = (byte)symmetricKeyAlgorithm; this.VerifyHashAlgorithm(); this.VerifySymmetricKeyAlgorithm(); }
/// <summary> /// Create a new key ring generator using old style checksumming. It is recommended to use /// SHA1 checksumming where possible. /// </summary> /// <param name="certificationLevel">The certification level for keys on this ring.</param> /// <param name="masterKey">The master key pair.</param> /// <param name="id">The id to be associated with the ring.</param> /// <param name="encAlgorithm">The algorithm to be used to protect secret keys.</param> /// <param name="passPhrase">The passPhrase to be used to protect secret keys.</param> /// <param name="hashedPackets">Packets to be included in the certification hash.</param> /// <param name="unhashedPackets">Packets to be attached unhashed to the certification.</param> /// <param name="rand">input secured random.</param> public PgpKeyRingGenerator( int certificationLevel, PgpKeyPair masterKey, string id, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, SecureRandom rand) : this(certificationLevel, masterKey, id, encAlgorithm, passPhrase, false, hashedPackets, unhashedPackets, rand) { }
public PgpSecretKey( int certificationLevel, PgpKeyPair keyPair, string id, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, ISecureRandom rand) : this(certificationLevel, keyPair, id, encAlgorithm, passPhrase, false, hashedPackets, unhashedPackets, rand) { }
public static DerObjectIdentifier GetKeyEncryptionOID(SymmetricKeyAlgorithmTag algID) { switch (algID) { case SymmetricKeyAlgorithmTag.Aes128: return NistObjectIdentifiers.IdAes128Wrap; case SymmetricKeyAlgorithmTag.Aes192: return NistObjectIdentifiers.IdAes192Wrap; case SymmetricKeyAlgorithmTag.Aes256: return NistObjectIdentifiers.IdAes256Wrap; default: throw new PgpException("unknown symmetric algorithm ID: " + algID); } }
public static int GetKeyLength(SymmetricKeyAlgorithmTag algID) { switch (algID) { case SymmetricKeyAlgorithmTag.Aes128: return 16; case SymmetricKeyAlgorithmTag.Aes192: return 24; case SymmetricKeyAlgorithmTag.Aes256: return 32; default: throw new PgpException("unknown symmetric algorithm ID: " + algID); } }
public PgpSecretKey( int certificationLevel, PgpKeyPair keyPair, string id, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSHA1, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, SecureRandom rand) : this(keyPair, encAlgorithm, passPhrase, useSHA1, rand) { try { this.trust = null; this.ids = new ArrayList(); ids.Add(id); this.idTrusts = new ArrayList(); idTrusts.Add(null); this.idSigs = new ArrayList(); PgpSignatureGenerator sGen = new PgpSignatureGenerator( keyPair.PublicKey.Algorithm, HashAlgorithmTag.Sha1); // // Generate the certification // sGen.InitSign(certificationLevel, keyPair.PrivateKey); sGen.SetHashedSubpackets(hashedPackets); sGen.SetUnhashedSubpackets(unhashedPackets); PgpSignature certification = sGen.GenerateCertification(id, keyPair.PublicKey); this.pub = PgpPublicKey.AddCertification(keyPair.PublicKey, id, certification); ArrayList sigList = new ArrayList(); sigList.Add(certification); idSigs.Add(sigList); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } }
public ECDHPublicBcpgKey( DerObjectIdentifier oid, ECPoint point, HashAlgorithmTag hashAlgorithm, SymmetricKeyAlgorithmTag symmetricKeyAlgorithm) : base(oid, point) { reserved = 1; hashFunctionId = hashAlgorithm; symAlgorithmId = symmetricKeyAlgorithm; VerifyHashAlgorithm(); VerifySymmetricKeyAlgorithm(); }
public PgpSecretKey( int certificationLevel, PgpKeyPair keyPair, string id, SymmetricKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm, char[] passPhrase, bool useSha1, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, ISecureRandom rand) : this(keyPair.PrivateKey, CertifiedPublicKey(certificationLevel, keyPair, id, hashedPackets, unhashedPackets, hashAlgorithm), encAlgorithm, passPhrase, useSha1, rand, true) { }
public SecretKeyPacket( PublicKeyPacket pubKeyPacket, SymmetricKeyAlgorithmTag encAlgorithm, int s2kUsage, S2k s2k, byte[] iv, byte[] secKeyData) { this.pubKeyPacket = pubKeyPacket; this.encAlgorithm = encAlgorithm; this.s2kUsage = s2kUsage; this.s2k = s2k; this.iv = Arrays.Clone(iv); this.secKeyData = secKeyData; }
public PgpSecretKey( int certificationLevel, PublicKeyAlgorithmTag algorithm, IAsymmetricKeyParameter pubKey, IAsymmetricKeyParameter privKey, DateTime time, string id, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, SecureRandom rand) : this(certificationLevel, new PgpKeyPair(algorithm, pubKey, privKey, time), id, encAlgorithm, passPhrase, hashedPackets, unhashedPackets, rand) { }
/// <param name="bcpgIn">The stream to read the packet from.</param> public ECDHPublicBcpgKey( BcpgInputStream bcpgIn) : base(bcpgIn) { int length = bcpgIn.ReadByte(); byte[] kdfParameters = new byte[length]; if (kdfParameters.Length != 3) throw new InvalidOperationException("kdf parameters size of 3 expected."); bcpgIn.ReadFully(kdfParameters); reserved = kdfParameters[0]; hashFunctionId = (HashAlgorithmTag)kdfParameters[1]; symAlgorithmId = (SymmetricKeyAlgorithmTag)kdfParameters[2]; VerifyHashAlgorithm(); VerifySymmetricKeyAlgorithm(); }
/// <summary> /// Create a new key ring generator. /// </summary> /// <param name="certificationLevel">The certification level for keys on this ring.</param> /// <param name="masterKey">The master key pair.</param> /// <param name="id">The id to be associated with the ring.</param> /// <param name="encAlgorithm">The algorithm to be used to protect secret keys.</param> /// <param name="passPhrase">The passPhrase to be used to protect secret keys.</param> /// <param name="useSha1">Checksum the secret keys with SHA1 rather than the older 16 bit checksum.</param> /// <param name="hashedPackets">Packets to be included in the certification hash.</param> /// <param name="unhashedPackets">Packets to be attached unhashed to the certification.</param> /// <param name="rand">input secured random.</param> public PgpKeyRingGenerator( int certificationLevel, PgpKeyPair masterKey, string id, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSha1, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, SecureRandom rand) { this.certificationLevel = certificationLevel; this.masterKey = masterKey; this.id = id; this.encAlgorithm = encAlgorithm; this.passPhrase = passPhrase; this.useSha1 = useSha1; this.hashedPacketVector = hashedPackets; this.unhashedPacketVector = unhashedPackets; this.rand = rand; keys.Add(new PgpSecretKey(certificationLevel, masterKey, id, encAlgorithm, passPhrase, useSha1, hashedPackets, unhashedPackets, rand)); }
public SecretKeyPacket( PublicKeyPacket pubKeyPacket, SymmetricKeyAlgorithmTag encAlgorithm, S2k s2k, byte[] iv, byte[] secKeyData) { this.pubKeyPacket = pubKeyPacket; this.encAlgorithm = encAlgorithm; if (encAlgorithm != SymmetricKeyAlgorithmTag.Null) { this.s2kUsage = UsageChecksum; } else { this.s2kUsage = UsageNone; } this.s2k = s2k; this.iv = Arrays.Clone(iv); this.secKeyData = secKeyData; }
public static KeyParameter MakeKeyFromPassPhrase( SymmetricKeyAlgorithmTag algorithm, S2k s2k, char[] passPhrase) { int keySize = GetKeySize(algorithm); byte[] pBytes = Strings.ToByteArray(new string(passPhrase)); byte[] keyBytes = new byte[(keySize + 7) / 8]; int generatedBytes = 0; int loopCount = 0; while (generatedBytes < keyBytes.Length) { IDigest digest; if (s2k != null) { string digestName = GetDigestName(s2k.HashAlgorithm); try { digest = DigestUtilities.GetDigest(digestName); } catch (Exception e) { throw new PgpException("can't find S2k digest", e); } for (int i = 0; i != loopCount; i++) { digest.Update(0); } byte[] iv = s2k.GetIV(); switch (s2k.Type) { case S2k.Simple: digest.BlockUpdate(pBytes, 0, pBytes.Length); break; case S2k.Salted: digest.BlockUpdate(iv, 0, iv.Length); digest.BlockUpdate(pBytes, 0, pBytes.Length); break; case S2k.SaltedAndIterated: long count = s2k.IterationCount; digest.BlockUpdate(iv, 0, iv.Length); digest.BlockUpdate(pBytes, 0, pBytes.Length); count -= iv.Length + pBytes.Length; while (count > 0) { if (count < iv.Length) { digest.BlockUpdate(iv, 0, (int)count); break; } else { digest.BlockUpdate(iv, 0, iv.Length); count -= iv.Length; } if (count < pBytes.Length) { digest.BlockUpdate(pBytes, 0, (int)count); count = 0; } else { digest.BlockUpdate(pBytes, 0, pBytes.Length); count -= pBytes.Length; } } break; default: throw new PgpException("unknown S2k type: " + s2k.Type); } } else { try { digest = DigestUtilities.GetDigest("MD5"); for (int i = 0; i != loopCount; i++) { digest.Update(0); } digest.BlockUpdate(pBytes, 0, pBytes.Length); } catch (Exception e) { throw new PgpException("can't find MD5 digest", e); } } byte[] dig = DigestUtilities.DoFinal(digest); if (dig.Length > (keyBytes.Length - generatedBytes)) { Array.Copy(dig, 0, keyBytes, generatedBytes, keyBytes.Length - generatedBytes); } else { Array.Copy(dig, 0, keyBytes, generatedBytes, dig.Length); } generatedBytes += dig.Length; loopCount++; } Array.Clear(pBytes, 0, pBytes.Length); return MakeKey(algorithm, keyBytes); }
/// <summary> /// Attempt to sign then encrypt a message using PGP with the specified private and public keys. /// </summary> /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param> /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param> /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param> /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <returns>Whether the encryption completed successfully.</returns> public bool PgpSignAndEncrypt(PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, IEnumerable <PgpPublicKey> recipientPublicKeys, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes) { // Ensure a valid encoding. if (BodyEncoding == null) { BodyEncoding = Encoding.UTF8; } // Attempt to sign. bool signedAndEncrypted = false; using (MemoryStream signedAndEncryptedMessageStream = new MemoryStream()) { // Attempt to encrypt the message. // OpaqueMail optional setting for protecting the subject. if (SubjectEncryption && !Body.StartsWith("Subject: ")) { signedAndEncrypted = Pgp.SignAndEncrypt(BodyEncoding.GetBytes("Subject: " + Subject + "\r\n" + Body), "", signedAndEncryptedMessageStream, senderPublicKey, senderPrivateKey, recipientPublicKeys, hashAlgorithmTag, symmetricKeyAlgorithmTag, true); } else { signedAndEncrypted = Pgp.SignAndEncrypt(BodyEncoding.GetBytes(Body), "", signedAndEncryptedMessageStream, senderPublicKey, senderPrivateKey, recipientPublicKeys, hashAlgorithmTag, symmetricKeyAlgorithmTag, true); } if (signedAndEncrypted) { // OpaqueMail optional setting for protecting the subject. if (SubjectEncryption) { Subject = "PGP Encrypted Message"; } signedAndEncrypted = true; RawBody = BodyEncoding.GetString(signedAndEncryptedMessageStream.ToArray()); } } return(signedAndEncrypted); }
/// <summary> /// Attempt to encrypt a message using PGP with the specified public key(s). /// </summary> /// <param name="messageStream">Stream containing the message to encrypt.</param> /// <param name="fileName">File name of for the message.</param> /// <param name="signedAndEncryptedMessageStream">Stream to write the encrypted message into.</param> /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param> /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param> /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param> /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <param name="armor">Whether to wrap the message with ASCII armor.</param> /// <returns>Whether the encryption completed successfully.</returns> public static bool SignAndEncrypt(Stream messageStream, string fileName, Stream signedAndEncryptedMessageStream, PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, IEnumerable <PgpPublicKey> recipientPublicKeys, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true) { // Create a signature generator. PgpSignatureGenerator signatureGenerator = new PgpSignatureGenerator(senderPublicKey.Algorithm, hashAlgorithmTag); signatureGenerator.InitSign(PgpSignature.BinaryDocument, senderPrivateKey); // Add the public key user ID. foreach (string userId in senderPublicKey.GetUserIds()) { PgpSignatureSubpacketGenerator signatureSubGenerator = new PgpSignatureSubpacketGenerator(); signatureSubGenerator.SetSignerUserId(false, userId); signatureGenerator.SetHashedSubpackets(signatureSubGenerator.Generate()); break; } // Allow any of the corresponding keys to be used for decryption. PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.TripleDes, true, new SecureRandom()); foreach (PgpPublicKey publicKey in recipientPublicKeys) { encryptedDataGenerator.AddMethod(publicKey); } // Handle optional ASCII armor. if (armor) { using (Stream armoredStream = new ArmoredOutputStream(signedAndEncryptedMessageStream)) { using (Stream encryptedStream = encryptedDataGenerator.Open(armoredStream, new byte[Constants.LARGEBUFFERSIZE])) { PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed); using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream)) { signatureGenerator.GenerateOnePassVersion(false).Encode(compressedStream); PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator(); using (Stream literalStream = literalDataGenerator.Open(compressedStream, PgpLiteralData.Binary, fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE])) { // Process each character in the message. int messageChar; while ((messageChar = messageStream.ReadByte()) >= 0) { literalStream.WriteByte((byte)messageChar); signatureGenerator.Update((byte)messageChar); } } signatureGenerator.Generate().Encode(compressedStream); } } } } else { using (Stream encryptedStream = encryptedDataGenerator.Open(signedAndEncryptedMessageStream, new byte[Constants.LARGEBUFFERSIZE])) { PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed); using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream)) { signatureGenerator.GenerateOnePassVersion(false).Encode(compressedStream); PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator(); using (Stream literalStream = literalDataGenerator.Open(compressedStream, PgpLiteralData.Binary, fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE])) { // Process each character in the message. int messageChar; while ((messageChar = messageStream.ReadByte()) >= 0) { literalStream.WriteByte((byte)messageChar); signatureGenerator.Update((byte)messageChar); } } signatureGenerator.Generate().Encode(compressedStream); } } } return(true); }
internal PgpSecretKey( PgpPrivateKey privKey, PgpPublicKey pubKey, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSha1, ISecureRandom rand, bool isMasterKey) { BcpgObject secKey; _pub = pubKey; switch (pubKey.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: case PublicKeyAlgorithmTag.RsaGeneral: var rsK = (RsaPrivateCrtKeyParameters)privKey.Key; secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q); break; case PublicKeyAlgorithmTag.Dsa: var dsK = (DsaPrivateKeyParameters)privKey.Key; secKey = new DsaSecretBcpgKey(dsK.X); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: var esK = (ElGamalPrivateKeyParameters)privKey.Key; secKey = new ElGamalSecretBcpgKey(esK.X); break; case PublicKeyAlgorithmTag.Ecdh: case PublicKeyAlgorithmTag.Ecdsa: var ecK = (ECPrivateKeyParameters)privKey.Key; secKey = new ECSecretBcpgKey(ecK.D); break; default: throw new PgpException("unknown key class"); } try { using (var bOut = new MemoryStream()) { using (var pOut = new BcpgOutputStream(bOut)) { pOut.WriteObject(secKey); var keyData = bOut.ToArray(); var checksumBytes = Checksum(useSha1, keyData, keyData.Length); pOut.Write(checksumBytes); var bOutData = bOut.ToArray(); if (encAlgorithm == SymmetricKeyAlgorithmTag.Null) { this._secret = isMasterKey ? new SecretKeyPacket(_pub.PublicKeyPacket, encAlgorithm, null, null, bOutData) : new SecretSubkeyPacket(_pub.PublicKeyPacket, encAlgorithm, null, null, bOutData); } else { S2k s2K; byte[] iv; var encData = EncryptKeyData(bOutData, encAlgorithm, passPhrase, rand, out s2K, out iv); var s2KUsage = useSha1 ? SecretKeyPacket.UsageSha1 : SecretKeyPacket.UsageChecksum; this._secret = isMasterKey ? new SecretKeyPacket(_pub.PublicKeyPacket, encAlgorithm, s2KUsage, s2K, iv, encData) : new SecretSubkeyPacket(_pub.PublicKeyPacket, encAlgorithm, s2KUsage, s2K, iv, encData); } } } } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } }
/// <summary> /// Attempt to encrypt a message using PGP with the specified public key(s). /// </summary> /// <param name="messageStream">Stream containing the message to encrypt.</param> /// <param name="encryptedMessageStream">Stream to write the encrypted message into.</param> /// <param name="fileName">File name of for the message.</param> /// <param name="recipientPublicKey">BouncyCastle public keys to be used for encryption.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <param name="armor">Whether to wrap the message with ASCII armor.</param> /// <returns>Whether the encryption completed successfully.</returns> public static bool Encrypt(Stream messageStream, Stream encryptedMessageStream, string fileName, PgpPublicKey recipientPublicKey, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true) { return(Encrypt(messageStream, encryptedMessageStream, fileName, new List <PgpPublicKey>() { recipientPublicKey }, symmetricKeyAlgorithmTag, armor)); }
/// <summary> /// Attempt to encrypt a message using PGP with the specified public key(s). /// </summary> /// <param name="message">Byte array containing the message to encrypt.</param> /// <param name="fileName">File name of for the message.</param> /// <param name="signedAndEncryptedMessageStream">Stream to write the signed and encrypted message into.</param> /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param> /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param> /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param> /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <param name="armor">Whether to wrap the message with ASCII armor.</param> /// <returns>Whether the encryption completed successfully.</returns> public static bool SignAndEncrypt(byte[] message, string fileName, Stream signedAndEncryptedMessageStream, PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, IEnumerable <PgpPublicKey> recipientPublicKeys, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true) { using (MemoryStream messageStream = new MemoryStream(message)) { return(SignAndEncrypt(messageStream, fileName, signedAndEncryptedMessageStream, senderPublicKey, senderPrivateKey, recipientPublicKeys, hashAlgorithmTag, symmetricKeyAlgorithmTag, armor)); } }
public PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag encAlgorithm, SecureRandom rand, bool oldFormat) { defAlgorithm = encAlgorithm; this.rand = rand; this.oldFormat = oldFormat; }
internal PbeMethod(SymmetricKeyAlgorithmTag encAlgorithm, S2k s2k, KeyParameter key) { base.encAlgorithm = encAlgorithm; this.s2k = s2k; base.key = key; }
public PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag encAlgorithm, SecureRandom rand) { defAlgorithm = encAlgorithm; this.rand = rand; }
public PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag encAlgorithm, bool withIntegrityPacket, SecureRandom rand) { defAlgorithm = encAlgorithm; this.rand = rand; this.withIntegrityPacket = withIntegrityPacket; }
/// <summary> /// Attempt to sign then encrypt a message using PGP with the specified private and public keys. /// </summary> /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param> /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param> /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param> /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <returns>Whether the encryption completed successfully.</returns> public bool PgpSignAndEncrypt(PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, IEnumerable <PgpPublicKey> recipientPublicKeys, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes) { // Ensure a valid encoding. if (BodyEncoding == null) { BodyEncoding = Encoding.UTF8; } // Attempt to sign. bool signedAndEncrypted = false; using (MemoryStream signedAndEncryptedMessageStream = new MemoryStream()) { // Attempt to encrypt the message. signedAndEncrypted = Pgp.SignAndEncrypt(BodyEncoding.GetBytes(Body), "", signedAndEncryptedMessageStream, senderPublicKey, senderPrivateKey, recipientPublicKeys, hashAlgorithmTag, symmetricKeyAlgorithmTag, true); if (signedAndEncrypted) { signedAndEncrypted = true; rawBody = BodyEncoding.GetString(signedAndEncryptedMessageStream.ToArray()); } } return(signedAndEncrypted); }
/// <summary> /// Attempt to sign then encrypt a message using PGP with the specified private and public keys. /// </summary> /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param> /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param> /// <param name="recipientPublicKey">BouncyCastle public key to be used for encryption.</param> /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <returns>Whether the encryption completed successfully.</returns> public bool PgpSignAndEncrypt(PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, PgpPublicKey recipientPublicKey, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes) { return(PgpSignAndEncrypt(senderPublicKey, senderPrivateKey, new List <PgpPublicKey>() { recipientPublicKey }, hashAlgorithmTag, symmetricKeyAlgorithmTag)); }
public PgpKeyRingGenerator(int certificationLevel, PgpKeyPair masterKey, string id, SymmetricKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm, bool utf8PassPhrase, char[] passPhrase, bool useSha1, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, SecureRandom rand) : this(certificationLevel, masterKey, id, encAlgorithm, hashAlgorithm, PgpUtilities.EncodePassPhrase(passPhrase, utf8PassPhrase), useSha1, hashedPackets, unhashedPackets, rand) { }
/// <summary> /// Attempt to encrypt a message using PGP with the specified public key(s). /// </summary> /// <param name="message">Byte array containing the message to encrypt.</param> /// <param name="encryptedMessageStream">Stream to write the encrypted message into.</param> /// <param name="fileName">File name of for the message.</param> /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <param name="armor">Whether to wrap the message with ASCII armor.</param> /// <returns>Whether the encryption completed successfully.</returns> public static bool Encrypt(byte[] message, Stream encryptedMessageStream, string fileName, IEnumerable <PgpPublicKey> recipientPublicKeys, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true) { using (MemoryStream messageStream = new MemoryStream(message)) { return(Encrypt(messageStream, encryptedMessageStream, fileName, recipientPublicKeys, symmetricKeyAlgorithmTag, armor)); } }
/// <summary> /// Create master signing key. /// </summary> /// <param name="identity"> /// Identity of the key. /// </param> /// <param name="password"> /// Password to protect the secret key. /// </param> /// <param name="expires"> /// Key expiry; null means never expires. /// </param> /// <param name="signKeyLength"> /// Length of the signing key. /// </param> /// <param name="signGenerator"> /// Generator for the signing key. /// </param> /// <param name="signingAlgorithm"> /// Signing algorithm. /// </param> /// <param name="symmetricAlgorithm"> /// Symmetric algorithm. /// </param> /// <returns> /// Returns the <see cref="PgpKeyRingGenerator"/> with the keyring properties /// thus far. /// </returns> public static PgpKeyRingGenerator CreateMasterSigningKey( string identity, string password, DateTime?expires, int signKeyLength = 2048, string signGenerator = "RSA", PublicKeyAlgorithmTag signingAlgorithm = PublicKeyAlgorithmTag.RsaSign, SymmetricKeyAlgorithmTag symmetricAlgorithm = SymmetricKeyAlgorithmTag.Aes256) { var keyringParameters = new KeyRingParameters(signKeyLength, signGenerator) { Password = password, Identity = identity, PrivateKeyEncryptionAlgorithm = symmetricAlgorithm, SymmetricAlgorithms = new[] { SymmetricKeyAlgorithmTag.Aes256, SymmetricKeyAlgorithmTag.Aes192, SymmetricKeyAlgorithmTag.Aes128 }, HashAlgorithms = new[] { HashAlgorithmTag.Sha256, HashAlgorithmTag.Sha1, HashAlgorithmTag.Sha384, HashAlgorithmTag.Sha512, HashAlgorithmTag.Sha224, } }; // master signing key var generator = GeneratorUtilities.GetKeyPairGenerator(signGenerator); generator.Init(keyringParameters.KeyParams); var masterKeyPair = new PgpKeyPair(signingAlgorithm, generator.GenerateKeyPair(), DateTime.UtcNow); Debug.WriteLine("Generated master key with ID " + masterKeyPair.KeyId.ToString("X")); var symmetricAlgorithms = (from a in keyringParameters.SymmetricAlgorithms select(int) a).ToArray(); var hashAlgorithms = (from a in keyringParameters.HashAlgorithms select(int) a).ToArray(); var masterSubpckGen = new PgpSignatureSubpacketGenerator(); masterSubpckGen.SetKeyFlags(false, PgpKeyFlags.CanSign | PgpKeyFlags.CanCertify); masterSubpckGen.SetPreferredSymmetricAlgorithms(false, symmetricAlgorithms); masterSubpckGen.SetPreferredHashAlgorithms(false, hashAlgorithms); if (expires != null) { masterSubpckGen.SetKeyExpirationTime(false, (long)((DateTime)expires - DateTime.Now).TotalSeconds); } // keyring -- adding master key return(new PgpKeyRingGenerator( PgpSignature.DefaultCertification, masterKeyPair, keyringParameters.Identity, keyringParameters.PrivateKeyEncryptionAlgorithm, keyringParameters.GetPassword(), true, masterSubpckGen.Generate(), null, new SecureRandom())); }
/// <summary> /// Attempt to encrypt a message using PGP with the specified public key(s). /// </summary> /// <param name="messageStream">Stream containing the message to encrypt.</param> /// <param name="encryptedMessage">If successful, the encrypted message.</param> /// <param name="fileName">File name of for the message.</param> /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <param name="armor">Whether to wrap the message with ASCII armor.</param> /// <returns>Whether the encryption completed successfully.</returns> public static bool Encrypt(Stream messageStream, out byte[] encryptedMessage, string fileName, IEnumerable <PgpPublicKey> recipientPublicKeys, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true) { using (MemoryStream encryptedMessageStream = new MemoryStream()) { bool encrypted = Encrypt(messageStream, encryptedMessageStream, fileName, recipientPublicKeys, symmetricKeyAlgorithmTag, armor); if (encrypted) { encryptedMessage = encryptedMessageStream.ToArray(); } else { encryptedMessage = null; } return(encrypted); } }
/// <summary> /// Export the public/private keypair. /// </summary> /// <param name="secretPath"> /// The secret output path. /// </param> /// <param name="publicPath"> /// The public output path. /// </param> /// <param name="publicKey"> /// The public key. /// </param> /// <param name="privateKey"> /// The private key. /// </param> /// <param name="identity"> /// The identity for the key. /// </param> /// <param name="passPhrase"> /// The pass phrase for the secret key file. /// </param> /// <param name="creationDate"> /// Date/time the key was created. /// </param> /// <param name="publicKeyAlgorithm"> /// The public key algorithm. /// </param> /// <param name="symmetricAlgorithm"> /// The symmetric key algorithm. /// </param> /// <param name="armor"> /// Should the keys be written using ASCII armor? /// </param> /// <returns> /// The <see cref="PgpSecretKey"/>. /// </returns> public static PgpSecretKey ExportKeyPair( string secretPath, string publicPath, AsymmetricKeyParameter publicKey, AsymmetricKeyParameter privateKey, string identity, char[] passPhrase, DateTime creationDate, PublicKeyAlgorithmTag publicKeyAlgorithm = PublicKeyAlgorithmTag.RsaGeneral, SymmetricKeyAlgorithmTag symmetricAlgorithm = SymmetricKeyAlgorithmTag.Aes256, bool armor = true) { var secretKey = new PgpSecretKey( PgpSignature.DefaultCertification, publicKeyAlgorithm, publicKey, privateKey, creationDate, identity, symmetricAlgorithm, passPhrase, null, null, new SecureRandom()); if (secretPath != null) { using (var secretOut = (Stream) new FileInfo(secretPath).OpenWrite()) { var secretOutputStream = secretOut; if (armor) { secretOutputStream = new ArmoredOutputStream(secretOut); } secretKey.Encode(secretOutputStream); secretOutputStream.Flush(); if (armor) { secretOutputStream.Dispose(); } } } if (publicPath != null) { using (var publicOut = (Stream) new FileInfo(publicPath).OpenWrite()) { var publicOutputStream = publicOut; if (armor) { publicOutputStream = new ArmoredOutputStream(publicOut); } var key = secretKey.PublicKey; key.Encode(publicOutputStream); publicOutputStream.Flush(); if (armor) { publicOutputStream.Dispose(); } } } return(secretKey); }
/// <summary> /// Attempt to encrypt a message using PGP with the specified public key(s). /// </summary> /// <param name="messageStream">Stream containing the message to encrypt.</param> /// <param name="encryptedMessageStream">Stream to write the encrypted message into.</param> /// <param name="fileName">File name of for the message.</param> /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <param name="armor">Whether to wrap the message with ASCII armor.</param> /// <returns>Whether the encryption completed successfully.</returns> public static bool Encrypt(Stream messageStream, Stream encryptedMessageStream, string fileName, IEnumerable <PgpPublicKey> recipientPublicKeys, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true) { // Allow any of the corresponding keys to be used for decryption. PgpEncryptedDataGenerator encryptedDataGenerator = new PgpEncryptedDataGenerator(symmetricKeyAlgorithmTag, true, new SecureRandom()); foreach (PgpPublicKey publicKey in recipientPublicKeys) { encryptedDataGenerator.AddMethod(publicKey); } // Handle optional ASCII armor. if (armor) { using (Stream armoredStream = new ArmoredOutputStream(encryptedMessageStream)) { using (Stream encryptedStream = encryptedDataGenerator.Open(armoredStream, new byte[Constants.LARGEBUFFERSIZE])) { PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed); using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream)) { PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator(); using (Stream literalDataStream = literalDataGenerator.Open(encryptedStream, PgpLiteralData.Binary, fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE])) { messageStream.Seek(0, SeekOrigin.Begin); messageStream.CopyTo(literalDataStream); } } } } } else { using (Stream encryptedStream = encryptedDataGenerator.Open(encryptedMessageStream, new byte[Constants.LARGEBUFFERSIZE])) { PgpCompressedDataGenerator compressedDataGenerator = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Uncompressed); using (Stream compressedStream = compressedDataGenerator.Open(encryptedStream)) { PgpLiteralDataGenerator literalDataGenerator = new PgpLiteralDataGenerator(); using (Stream literalDataStream = literalDataGenerator.Open(encryptedStream, PgpLiteralData.Binary, fileName, DateTime.Now, new byte[Constants.LARGEBUFFERSIZE])) { messageStream.Seek(0, SeekOrigin.Begin); messageStream.CopyTo(literalDataStream); } } } } return(true); }
/// <summary> /// Generate public/secret key ring file. /// </summary> /// <param name="identity"> /// The identity. /// </param> /// <param name="password"> /// The password. /// </param> /// <param name="publicKeyFile"> /// The public key file path. /// </param> /// <param name="privateKeyFile"> /// The private key file path. /// </param> /// <param name="expires"> /// When, if ever, should the key expire; null means never. /// </param> /// <param name="armor"> /// Should output as ASCII armor? /// </param> /// <param name="signKeyLength"> /// Signing keypair length. /// </param> /// <param name="signGenerator"> /// Signing key generator type. /// </param> /// <param name="signingAlgorithm"> /// The signing algorithm. /// </param> /// <param name="encryptKeyLength"> /// Encryption keypair length. /// </param> /// <param name="encryptGenerator"> /// Encryption key generator type. /// </param> /// <param name="encryptionAlgorithm"> /// The encryption algorithm. /// </param> /// <param name="symmetricAlgorithm"> /// The symmetric encryption algorithm. /// </param> public static void GenerateKeyRing( string identity, string password, string publicKeyFile, string privateKeyFile, DateTime?expires, bool armor = false, int signKeyLength = 2048, string signGenerator = "RSA", PublicKeyAlgorithmTag signingAlgorithm = PublicKeyAlgorithmTag.RsaSign, int encryptKeyLength = 2048, string encryptGenerator = "RSA", PublicKeyAlgorithmTag encryptionAlgorithm = PublicKeyAlgorithmTag.RsaEncrypt, SymmetricKeyAlgorithmTag symmetricAlgorithm = SymmetricKeyAlgorithmTag.Aes256) { var krgen = CreateKeyRingGenerator( identity, password, expires, signKeyLength, signGenerator, signingAlgorithm, encryptKeyLength, encryptGenerator, encryptionAlgorithm, symmetricAlgorithm); // Generate public key ring, dump to file. var pkr = krgen.GeneratePublicKeyRing(); using (var pubout = (Stream) new FileStream(publicKeyFile, FileMode.Create)) { Stream wrapped = pubout; if (armor) { wrapped = new ArmoredOutputStream(pubout); } pkr.Encode(wrapped); wrapped.Flush(); if (armor) { wrapped.Dispose(); } } // Generate private key, dump to file. var skr = krgen.GenerateSecretKeyRing(); using (var secout = (Stream) new FileStream(privateKeyFile, FileMode.Create)) { Stream wrapped = secout; if (armor) { wrapped = new ArmoredOutputStream(secout); } skr.Encode(wrapped); wrapped.Flush(); if (armor) { wrapped.Dispose(); } } }
/// <summary> /// Attempt to encrypt a message using PGP with the specified public key(s). /// </summary> /// <param name="messageStream">Stream containing the message to encrypt.</param> /// <param name="fileName">File name of for the message.</param> /// <param name="signedAndEncryptedMessage">If successful, the encrypted message.</param> /// <param name="senderPublicKey">The BouncyCastle public key associated with the signature.</param> /// <param name="senderPrivateKey">The BouncyCastle private key to be used for signing.</param> /// <param name="recipientPublicKeys">Collection of BouncyCastle public keys to be used for encryption.</param> /// <param name="hashAlgorithmTag">The hash algorithm tag to use for signing.</param> /// <param name="symmetricKeyAlgorithmTag">The symmetric key algorithm tag to use for encryption.</param> /// <param name="armor">Whether to wrap the message with ASCII armor.</param> /// <returns>Whether the encryption completed successfully.</returns> public static bool SignAndEncrypt(Stream messageStream, string fileName, out byte[] signedAndEncryptedMessage, PgpPublicKey senderPublicKey, PgpPrivateKey senderPrivateKey, IEnumerable <PgpPublicKey> recipientPublicKeys, HashAlgorithmTag hashAlgorithmTag = HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag symmetricKeyAlgorithmTag = SymmetricKeyAlgorithmTag.TripleDes, bool armor = true) { using (MemoryStream signedAndEncryptedMessageStream = new MemoryStream()) { if (SignAndEncrypt(messageStream, fileName, signedAndEncryptedMessageStream, senderPublicKey, senderPrivateKey, recipientPublicKeys, hashAlgorithmTag, symmetricKeyAlgorithmTag, armor)) { signedAndEncryptedMessage = signedAndEncryptedMessageStream.ToArray(); return(true); } else { signedAndEncryptedMessage = null; return(false); } } }
internal static byte[] MakeKeyFromPassPhrase( IDigestFactory <PgpDigestTypeIdentifier> digestFactory, SymmetricKeyAlgorithmTag algorithm, S2k s2k, char[] passPhrase) { int keySize = 0; switch (algorithm) { case SymmetricKeyAlgorithmTag.TripleDes: keySize = 192; break; case SymmetricKeyAlgorithmTag.Idea: keySize = 128; break; case SymmetricKeyAlgorithmTag.Cast5: keySize = 128; break; case SymmetricKeyAlgorithmTag.Blowfish: keySize = 128; break; case SymmetricKeyAlgorithmTag.Safer: keySize = 128; break; case SymmetricKeyAlgorithmTag.Des: keySize = 64; break; case SymmetricKeyAlgorithmTag.Aes128: keySize = 128; break; case SymmetricKeyAlgorithmTag.Aes192: keySize = 192; break; case SymmetricKeyAlgorithmTag.Aes256: keySize = 256; break; case SymmetricKeyAlgorithmTag.Twofish: keySize = 256; break; case SymmetricKeyAlgorithmTag.Camellia128: keySize = 128; break; case SymmetricKeyAlgorithmTag.Camellia192: keySize = 192; break; case SymmetricKeyAlgorithmTag.Camellia256: keySize = 256; break; default: throw new PgpException("unknown symmetric algorithm: " + algorithm); } byte[] pBytes = Strings.ToUtf8ByteArray(passPhrase); byte[] keyBytes = new byte[(keySize + 7) / 8]; int generatedBytes = 0; int loopCount = 0; if (s2k != null) { if (s2k.HashAlgorithm != digestFactory.AlgorithmDetails.Algorithm) { throw new PgpException("s2k/digestFactory mismatch"); } } else { if (digestFactory.AlgorithmDetails.Algorithm != HashAlgorithmTag.MD5) { throw new PgpException("digestFactory not for MD5"); } } IStreamCalculator <IBlockResult> digestCalculator = digestFactory.CreateCalculator(); Stream dOut = digestCalculator.Stream; try { while (generatedBytes < keyBytes.Length) { if (s2k != null) { for (int i = 0; i != loopCount; i++) { dOut.WriteByte(0); } byte[] iv = s2k.GetIV(); switch (s2k.Type) { case S2k.Simple: dOut.Write(pBytes, 0, pBytes.Length); break; case S2k.Salted: dOut.Write(iv, 0, iv.Length); dOut.Write(pBytes, 0, pBytes.Length); break; case S2k.SaltedAndIterated: long count = s2k.IterationCount; dOut.Write(iv, 0, iv.Length); dOut.Write(pBytes, 0, pBytes.Length); count -= iv.Length + pBytes.Length; while (count > 0) { if (count < iv.Length) { dOut.Write(iv, 0, (int)count); break; } else { dOut.Write(iv, 0, iv.Length); count -= iv.Length; } if (count < pBytes.Length) { dOut.Write(pBytes, 0, (int)count); count = 0; } else { dOut.Write(pBytes, 0, pBytes.Length); count -= pBytes.Length; } } break; default: throw new PgpException("unknown S2K type: " + s2k.Type); } } else { for (int i = 0; i != loopCount; i++) { dOut.WriteByte((byte)0); } dOut.Write(pBytes, 0, pBytes.Length); } dOut.Close(); byte[] dig = digestCalculator.GetResult().Collect(); if (dig.Length > (keyBytes.Length - generatedBytes)) { Array.Copy(dig, 0, keyBytes, generatedBytes, keyBytes.Length - generatedBytes); } else { Array.Copy(dig, 0, keyBytes, generatedBytes, dig.Length); } generatedBytes += dig.Length; loopCount++; } } catch (IOException e) { throw new PgpException("exception calculating digest: " + e.Message, e); } for (int i = 0; i != pBytes.Length; i++) { pBytes[i] = 0; } return(keyBytes); }
public PgpKeyRingGenerator(int certificationLevel, PgpKeyPair masterKey, string id, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, SecureRandom rand) : this(certificationLevel, masterKey, id, encAlgorithm, passPhrase, useSha1 : false, hashedPackets, unhashedPackets, rand) { }
/// <remarks> /// Allows the caller to handle the encoding of the passphrase to bytes. /// </remarks> public static KeyParameter MakeKeyFromPassPhraseRaw(SymmetricKeyAlgorithmTag algorithm, S2k s2k, byte[] rawPassPhrase) { return(DoMakeKeyFromPassPhrase(algorithm, s2k, rawPassPhrase, false)); }
/// <summary> /// Return a copy of the passed in secret key, encrypted using a new password /// and the passed in algorithm. /// </summary> /// <param name="key">The PgpSecretKey to be copied.</param> /// <param name="oldPassPhrase">The current password for the key.</param> /// <param name="newPassPhrase">The new password for the key.</param> /// <param name="newEncAlgorithm">The algorithm to be used for the encryption.</param> /// <param name="rand">Source of randomness.</param> public static PgpSecretKey CopyWithNewPassword(IPgpSecretKey key, char[] oldPassPhrase, char[] newPassPhrase, SymmetricKeyAlgorithmTag newEncAlgorithm, SecureRandom rand) { var rawKeyData = key.ExtractKeyData(oldPassPhrase); var s2KUsage = key.SecretPacket.S2KUsage; byte[] iv = null; S2k s2K = null; byte[] keyData; if (newEncAlgorithm == SymmetricKeyAlgorithmTag.Null) { s2KUsage = SecretKeyPacket.UsageNone; if (key.SecretPacket.S2KUsage == SecretKeyPacket.UsageSha1) // SHA-1 hash, need to rewrite Checksum { keyData = new byte[rawKeyData.Length - 18]; Array.Copy(rawKeyData, 0, keyData, 0, keyData.Length - 2); var check = Checksum(false, keyData, keyData.Length - 2); keyData[keyData.Length - 2] = check[0]; keyData[keyData.Length - 1] = check[1]; } else { keyData = rawKeyData; } } else { try { keyData = EncryptKeyData(rawKeyData, newEncAlgorithm, newPassPhrase, rand, out s2K, out iv); } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } } SecretKeyPacket secret; if (key.SecretPacket is SecretSubkeyPacket) { secret = new SecretSubkeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } else { secret = new SecretKeyPacket(key.SecretPacket.PublicKeyPacket, newEncAlgorithm, s2KUsage, s2K, iv, keyData); } return(new PgpSecretKey(secret, key.PublicKey)); }
public PgpEncryptedDataGenerator( SymmetricKeyAlgorithmTag encAlgorithm) { this.defAlgorithm = encAlgorithm; this.rand = new SecureRandom(); }
private byte[] ExtractKeyData( char[] passPhrase) { SymmetricKeyAlgorithmTag alg = secret.EncAlgorithm; byte[] encData = secret.GetSecretKeyData(); if (alg == SymmetricKeyAlgorithmTag.Null) { return(encData); } byte[] data; IBufferedCipher c = null; try { string cName = PgpUtilities.GetSymmetricCipherName(alg); c = CipherUtilities.GetCipher(cName + "/CFB/NoPadding"); } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } // TODO Factor this block out as 'encryptData' try { KeyParameter key = PgpUtilities.MakeKeyFromPassPhrase(secret.EncAlgorithm, secret.S2k, passPhrase); byte[] iv = secret.GetIV(); if (secret.PublicKeyPacket.Version == 4) { c.Init(false, new ParametersWithIV(key, iv)); data = c.DoFinal(encData); bool useSha1 = secret.S2kUsage == SecretKeyPacket.UsageSha1; byte[] check = Checksum(useSha1, data, (useSha1) ? data.Length - 20 : data.Length - 2); for (int i = 0; i != check.Length; i++) { if (check[i] != data[data.Length - check.Length + i]) { throw new PgpException("Checksum mismatch at " + i + " of " + check.Length); } } } else // version 2 or 3, RSA only. { data = new byte[encData.Length]; // // read in the four numbers // int pos = 0; for (int i = 0; i != 4; i++) { c.Init(false, new ParametersWithIV(key, iv)); int encLen = (((encData[pos] << 8) | (encData[pos + 1] & 0xff)) + 7) / 8; data[pos] = encData[pos]; data[pos + 1] = encData[pos + 1]; pos += 2; c.DoFinal(encData, pos, encLen, data, pos); pos += encLen; if (i != 3) { Array.Copy(encData, pos - iv.Length, iv, 0, iv.Length); } } // // verify Checksum // int cs = ((encData[pos] << 8) & 0xff00) | (encData[pos + 1] & 0xff); int calcCs = 0; for (int j = 0; j < data.Length - 2; j++) { calcCs += data[j] & 0xff; } calcCs &= 0xffff; if (calcCs != cs) { throw new PgpException("Checksum mismatch: passphrase wrong, expected " + cs.ToString("X") + " found " + calcCs.ToString("X")); } } return(data); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception decrypting key", e); } }
public PgpKeyRingGenerator(int certificationLevel, PgpKeyPair masterKey, string id, SymmetricKeyAlgorithmTag encAlgorithm, HashAlgorithmTag hashAlgorithm, byte[] rawPassPhrase, bool useSha1, PgpSignatureSubpacketVector hashedPackets, PgpSignatureSubpacketVector unhashedPackets, SecureRandom rand) { this.certificationLevel = certificationLevel; this.masterKey = masterKey; this.id = id; this.encAlgorithm = encAlgorithm; this.rawPassPhrase = rawPassPhrase; this.useSha1 = useSha1; hashedPacketVector = hashedPackets; unhashedPacketVector = unhashedPackets; this.rand = rand; this.hashAlgorithm = hashAlgorithm; keys.Add(new PgpSecretKey(certificationLevel, masterKey, id, encAlgorithm, hashAlgorithm, rawPassPhrase, clearPassPhrase: false, useSha1, hashedPackets, unhashedPackets, rand)); }
internal PgpSecretKey( PgpPrivateKey privKey, PgpPublicKey pubKey, SymmetricKeyAlgorithmTag encAlgorithm, char[] passPhrase, bool useSha1, SecureRandom rand, bool isMasterKey) { BcpgObject secKey; this.pub = pubKey; switch (pubKey.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaSign: case PublicKeyAlgorithmTag.RsaGeneral: RsaPrivateCrtKeyParameters rsK = (RsaPrivateCrtKeyParameters)privKey.Key; secKey = new RsaSecretBcpgKey(rsK.Exponent, rsK.P, rsK.Q); break; case PublicKeyAlgorithmTag.Dsa: DsaPrivateKeyParameters dsK = (DsaPrivateKeyParameters)privKey.Key; secKey = new DsaSecretBcpgKey(dsK.X); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: ElGamalPrivateKeyParameters esK = (ElGamalPrivateKeyParameters)privKey.Key; secKey = new ElGamalSecretBcpgKey(esK.X); break; default: throw new PgpException("unknown key class"); } try { MemoryStream bOut = new MemoryStream(); BcpgOutputStream pOut = new BcpgOutputStream(bOut); pOut.WriteObject(secKey); byte[] keyData = bOut.ToArray(); byte[] checksumBytes = Checksum(useSha1, keyData, keyData.Length); pOut.Write(checksumBytes); byte[] bOutData = bOut.ToArray(); if (encAlgorithm == SymmetricKeyAlgorithmTag.Null) { if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, null, null, bOutData); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, null, null, bOutData); } } else { S2k s2k; byte[] iv; byte[] encData = EncryptKeyData(bOutData, encAlgorithm, passPhrase, rand, out s2k, out iv); int s2kUsage = useSha1 ? SecretKeyPacket.UsageSha1 : SecretKeyPacket.UsageChecksum; if (isMasterKey) { this.secret = new SecretKeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } else { this.secret = new SecretSubkeyPacket(pub.publicPk, encAlgorithm, s2kUsage, s2k, iv, encData); } } } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception encrypting key", e); } }
/// <remarks> /// The passphrase is encoded to bytes using UTF8 (Encoding.UTF8.GetBytes). /// </remarks> public static KeyParameter MakeKeyFromPassPhraseUtf8(SymmetricKeyAlgorithmTag algorithm, S2k s2k, char[] passPhrase) { return(DoMakeKeyFromPassPhrase(algorithm, s2k, EncodePassPhrase(passPhrase, true), true)); }
public static string GetSymmetricCipherName( SymmetricKeyAlgorithmTag algorithm) { switch (algorithm) { case SymmetricKeyAlgorithmTag.Null: return null; case SymmetricKeyAlgorithmTag.TripleDes: return "DESEDE"; case SymmetricKeyAlgorithmTag.Idea: return "IDEA"; case SymmetricKeyAlgorithmTag.Cast5: return "CAST5"; case SymmetricKeyAlgorithmTag.Blowfish: return "Blowfish"; case SymmetricKeyAlgorithmTag.Safer: return "SAFER"; case SymmetricKeyAlgorithmTag.Des: return "DES"; case SymmetricKeyAlgorithmTag.Aes128: return "AES"; case SymmetricKeyAlgorithmTag.Aes192: return "AES"; case SymmetricKeyAlgorithmTag.Aes256: return "AES"; case SymmetricKeyAlgorithmTag.Twofish: return "Twofish"; default: throw new PgpException("unknown symmetric algorithm: " + algorithm); } }
internal Stream DoGetDataStream(byte[] rawPassPhrase, bool clearPassPhrase) { try { SymmetricKeyAlgorithmTag keyAlgorithm = keyData.EncAlgorithm; KeyParameter key = PgpUtilities.DoMakeKeyFromPassPhrase( keyAlgorithm, keyData.S2k, rawPassPhrase, clearPassPhrase); byte[] secKeyData = keyData.GetSecKeyData(); if (secKeyData != null && secKeyData.Length > 0) { IBufferedCipher keyCipher = CipherUtilities.GetCipher( PgpUtilities.GetSymmetricCipherName(keyAlgorithm) + "/CFB/NoPadding"); keyCipher.Init(false, new ParametersWithIV(key, new byte[keyCipher.GetBlockSize()])); byte[] keyBytes = keyCipher.DoFinal(secKeyData); keyAlgorithm = (SymmetricKeyAlgorithmTag)keyBytes[0]; key = ParameterUtilities.CreateKeyParameter( PgpUtilities.GetSymmetricCipherName(keyAlgorithm), keyBytes, 1, keyBytes.Length - 1); } IBufferedCipher c = CreateStreamCipher(keyAlgorithm); byte[] iv = new byte[c.GetBlockSize()]; c.Init(false, new ParametersWithIV(key, iv)); encStream = BcpgInputStream.Wrap(new CipherStream(encData.GetInputStream(), c, null)); if (encData is SymmetricEncIntegrityPacket) { truncStream = new TruncatedStream(encStream); string digestName = PgpUtilities.GetDigestName(HashAlgorithmTag.Sha1); IDigest digest = DigestUtilities.GetDigest(digestName); encStream = new DigestStream(truncStream, digest, null); } if (Streams.ReadFully(encStream, iv, 0, iv.Length) < iv.Length) { throw new EndOfStreamException("unexpected end of stream."); } int v1 = encStream.ReadByte(); int v2 = encStream.ReadByte(); if (v1 < 0 || v2 < 0) { throw new EndOfStreamException("unexpected end of stream."); } // Note: the oracle attack on the "quick check" bytes is not deemed // a security risk for PBE (see PgpPublicKeyEncryptedData) bool repeatCheckPassed = iv[iv.Length - 2] == (byte)v1 && iv[iv.Length - 1] == (byte)v2; // Note: some versions of PGP appear to produce 0 for the extra // bytes rather than repeating the two previous bytes bool zeroesCheckPassed = v1 == 0 && v2 == 0; if (!repeatCheckPassed && !zeroesCheckPassed) { throw new PgpDataValidationException("quick check failed."); } return(encStream); } catch (PgpException e) { throw e; } catch (Exception e) { throw new PgpException("Exception creating cipher", e); } }