Exemple #1
0
        public static KeyParameter MakeKeyFromPassPhrase(SymmetricKeyAlgorithmTag algorithm, IS2k s2k, char[] passPhrase)
        {
            var keySize  = GetKeySize(algorithm);
            var pBytes   = Strings.ToByteArray(new string(passPhrase));
            var keyBytes = new byte[(keySize + 7) / 8];

            var generatedBytes = 0;
            var loopCount      = 0;

            while (generatedBytes < keyBytes.Length)
            {
                IDigest digest;
                if (s2k != null)
                {
                    var digestName = GetDigestName(s2k.HashAlgorithm);

                    try
                    {
                        digest = DigestUtilities.GetDigest(digestName);
                    }
                    catch (Exception e)
                    {
                        throw new PgpException("can't find S2k digest", e);
                    }

                    for (var i = 0; i != loopCount; i++)
                    {
                        digest.Update(0);
                    }

                    var 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:
                        var 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;
                            }
                            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 (var 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);
                    }
                }

                var 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));
        }
        public static KeyParameter MakeKeyFromPassPhrase(SymmetricKeyAlgorithmTag algorithm, IS2k s2k, char[] passPhrase)
        {
            var keySize = GetKeySize(algorithm);
            var pBytes = Strings.ToByteArray(new string(passPhrase));
            var keyBytes = new byte[(keySize + 7) / 8];

            var generatedBytes = 0;
            var loopCount = 0;

            while (generatedBytes < keyBytes.Length)
            {
                IDigest digest;
                if (s2k != null)
                {
                    var digestName = GetDigestName(s2k.HashAlgorithm);

                    try
                    {
                        digest = DigestUtilities.GetDigest(digestName);
                    }
                    catch (Exception e)
                    {
                        throw new PgpException("can't find S2k digest", e);
                    }

                    for (var i = 0; i != loopCount; i++)
                    {
                        digest.Update(0);
                    }

                    var 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:
                            var 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;
                                }
                                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 (var 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);
                    }
                }

                var 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);
        }