/// <summary>Add a PBE encryption method to the encrypted object.</summary>
        public void AddMethod(ReadOnlySpan <byte> rawPassPhrase, PgpHashAlgorithm s2kDigest)
        {
            S2k s2k = PgpUtilities.GenerateS2k(s2kDigest, 0x60);

            byte[] key = new byte[PgpUtilities.GetKeySize(defAlgorithm) / 8];
            S2kBasedEncryption.MakeKey(rawPassPhrase, s2kDigest, s2k.GetIV(), s2k.IterationCount, key);
            methods.Add(new PbeMethod(defAlgorithm, s2k, key));
        }
Пример #2
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)
                {
                    try
                    {
                        switch (s2k.HashAlgorithm)
                        {
							case HashAlgorithmTag.Sha1:
								digest = DigestUtilities.GetDigest("SHA1");
								break;
							default:
								throw new PgpException("unknown hash algorithm: " + s2k.HashAlgorithm);
                        }
                    }
                    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);
        }
Пример #3
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));
        }
Пример #4
0
		public static KeyParameter MakeKeyFromPassPhrase(
            SymmetricKeyAlgorithmTag	algorithm,
            S2k							s2k,
            char[]						passPhrase)
        {
			// Changed pBytes to get string via encoding
			// this should use the OS encoding.
			//
			// vvv EDDINGTON
			var encoding = System.Text.Encoding.UTF8;

			int keySize = GetKeySize(algorithm);
			byte[] pBytes = encoding.GetBytes(new string(passPhrase));
			byte[] keyBytes = new byte[(keySize + 7) / 8];
			// ^^^ EDDINGTON

			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);
        }
Пример #5
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);
        }
Пример #6
0
        internal static KeyParameter DoMakeKeyFromPassPhrase(SymmetricKeyAlgorithmTag algorithm, S2k s2k, byte[] rawPassPhrase, bool clearPassPhrase)
        {
            int keySize = GetKeySize(algorithm);

            byte[] array = new byte[(keySize + 7) / 8];
            int    num   = 0;
            int    num2  = 0;

            while (num < array.Length)
            {
                IDigest digest;
                if (s2k != null)
                {
                    string digestName = GetDigestName(s2k.HashAlgorithm);
                    try
                    {
                        digest = DigestUtilities.GetDigest(digestName);
                    }
                    catch (global::System.Exception exception)
                    {
                        throw new PgpException("can't find S2k digest", exception);
                    }
                    for (int i = 0; i != num2; i++)
                    {
                        digest.Update(0);
                    }
                    byte[] iV = s2k.GetIV();
                    switch (s2k.Type)
                    {
                    case 0:
                        digest.BlockUpdate(rawPassPhrase, 0, rawPassPhrase.Length);
                        break;

                    case 1:
                        digest.BlockUpdate(iV, 0, iV.Length);
                        digest.BlockUpdate(rawPassPhrase, 0, rawPassPhrase.Length);
                        break;

                    case 3:
                    {
                        long iterationCount = s2k.IterationCount;
                        digest.BlockUpdate(iV, 0, iV.Length);
                        digest.BlockUpdate(rawPassPhrase, 0, rawPassPhrase.Length);
                        iterationCount -= iV.Length + rawPassPhrase.Length;
                        while (iterationCount > 0)
                        {
                            if (iterationCount < iV.Length)
                            {
                                digest.BlockUpdate(iV, 0, (int)iterationCount);
                                break;
                            }
                            digest.BlockUpdate(iV, 0, iV.Length);
                            iterationCount -= iV.Length;
                            if (iterationCount < rawPassPhrase.Length)
                            {
                                digest.BlockUpdate(rawPassPhrase, 0, (int)iterationCount);
                                iterationCount = 0L;
                            }
                            else
                            {
                                digest.BlockUpdate(rawPassPhrase, 0, rawPassPhrase.Length);
                                iterationCount -= rawPassPhrase.Length;
                            }
                        }
                        break;
                    }

                    default:
                        throw new PgpException(string.Concat((object)"unknown S2k type: ", (object)s2k.Type));
                    }
                }
                else
                {
                    try
                    {
                        digest = DigestUtilities.GetDigest("MD5");
                        for (int j = 0; j != num2; j++)
                        {
                            digest.Update(0);
                        }
                        digest.BlockUpdate(rawPassPhrase, 0, rawPassPhrase.Length);
                    }
                    catch (global::System.Exception exception2)
                    {
                        throw new PgpException("can't find MD5 digest", exception2);
                    }
                }
                byte[] array2 = DigestUtilities.DoFinal(digest);
                if (array2.Length > array.Length - num)
                {
                    global::System.Array.Copy((global::System.Array)array2, 0, (global::System.Array)array, num, array.Length - num);
                }
                else
                {
                    global::System.Array.Copy((global::System.Array)array2, 0, (global::System.Array)array, num, array2.Length);
                }
                num += array2.Length;
                num2++;
            }
            if (clearPassPhrase && rawPassPhrase != null)
            {
                global::System.Array.Clear((global::System.Array)rawPassPhrase, 0, rawPassPhrase.Length);
            }
            return(MakeKey(algorithm, array));
        }