Exemplo n.º 1
0
        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;
 }
Exemplo n.º 13
0
		public SecretSubkeyPacket(
            PublicKeyPacket				pubKeyPacket,
            SymmetricKeyAlgorithmTag	encAlgorithm,
            S2k							s2k,
            byte[]						iv,
            byte[]						secKeyData)
            : base(pubKeyPacket, encAlgorithm, s2k, iv, secKeyData)
        {
        }
Exemplo n.º 14
0
		internal PgpSecretKey(
			PgpPrivateKey				privKey,
			PgpPublicKey				pubKey,
			SymmetricKeyAlgorithmTag	encAlgorithm,
			char[]						passPhrase,
			bool						useSha1,
			SecureRandom				rand)
			: this(privKey, pubKey, encAlgorithm, passPhrase, useSha1, rand, false)
		{
		}
Exemplo n.º 15
0
        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)
 {
 }
Exemplo n.º 20
0
 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);
     }
 }
Exemplo n.º 21
0
 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);
     }
 }
Exemplo n.º 22
0
        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);
            }
        }
Exemplo n.º 23
0
        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)
 {
 }
Exemplo n.º 25
0
        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)
 {
 }
Exemplo n.º 27
0
        /// <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));
        }
Exemplo n.º 29
0
		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;
        }
Exemplo n.º 30
0
		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);
        }
Exemplo n.º 31
0
        /// <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);
        }
Exemplo n.º 32
0
        /// <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);
        }
Exemplo n.º 33
0
        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);
            }
        }
Exemplo n.º 34
0
 /// <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));
 }
Exemplo n.º 35
0
 /// <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));
     }
 }
Exemplo n.º 36
0
 public PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag encAlgorithm, SecureRandom rand, bool oldFormat)
 {
     defAlgorithm   = encAlgorithm;
     this.rand      = rand;
     this.oldFormat = oldFormat;
 }
Exemplo n.º 37
0
 internal PbeMethod(SymmetricKeyAlgorithmTag encAlgorithm, S2k s2k, KeyParameter key)
 {
     base.encAlgorithm = encAlgorithm;
     this.s2k          = s2k;
     base.key          = key;
 }
Exemplo n.º 38
0
 public PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag encAlgorithm, SecureRandom rand)
 {
     defAlgorithm = encAlgorithm;
     this.rand    = rand;
 }
Exemplo n.º 39
0
 public PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag encAlgorithm, bool withIntegrityPacket, SecureRandom rand)
 {
     defAlgorithm             = encAlgorithm;
     this.rand                = rand;
     this.withIntegrityPacket = withIntegrityPacket;
 }
Exemplo n.º 40
0
        /// <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);
        }
Exemplo n.º 41
0
 /// <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));
 }
Exemplo n.º 42
0
 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)
 {
 }
Exemplo n.º 43
0
 /// <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()));
        }
Exemplo n.º 45
0
        /// <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);
        }
Exemplo n.º 47
0
        /// <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();
                }
            }
        }
Exemplo n.º 49
0
 /// <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);
         }
     }
 }
Exemplo n.º 50
0
        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);
        }
Exemplo n.º 51
0
 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)
 {
 }
Exemplo n.º 52
0
 /// <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));
 }
Exemplo n.º 53
0
        /// <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));
        }
Exemplo n.º 54
0
 public PgpEncryptedDataGenerator(
     SymmetricKeyAlgorithmTag encAlgorithm)
 {
     this.defAlgorithm = encAlgorithm;
     this.rand         = new SecureRandom();
 }
Exemplo n.º 55
0
        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);
            }
        }
Exemplo n.º 56
0
 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));
 }
Exemplo n.º 57
0
        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);
            }
        }
Exemplo n.º 58
0
 /// <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));
 }
Exemplo n.º 59
0
		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);
            }
        }
Exemplo n.º 60
0
        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);
            }
        }