Beispiel #1
0
        public void StretchedSecret()
        {
            var cipher = "AES-256";
            var hash   = "SHA256";
            var secret = new byte[] { 195, 191, 209, 165, 209, 201, 127, 122, 136, 111, 31, 66, 111, 68, 38, 155, 216, 204, 46, 181, 200, 188, 170, 204, 104, 74, 239, 251, 173, 114, 222, 234 };

            StretchedKey.Generate(cipher, hash, secret, out StretchedKey k1, out StretchedKey k2);

            Assert.IsNotNull(k1);
            CollectionAssert.AreEqual(new byte[] { 208, 132, 203, 169, 253, 52, 40, 83, 161, 91, 17, 71, 33, 136, 67, 96 }, k1.IV);
            CollectionAssert.AreEqual(new byte[] { 156, 48, 241, 157, 92, 248, 153, 186, 114, 127, 195, 114, 106, 104, 215, 133, 35, 11, 131, 137, 123, 70, 74, 26, 15, 60, 189, 32, 67, 221, 115, 137 }, k1.CipherKey);
            CollectionAssert.AreEqual(new byte[] { 6, 179, 91, 245, 224, 56, 153, 120, 77, 140, 29, 5, 15, 213, 187, 65, 137, 230, 202, 120 }, k1.MacKey);

            Assert.IsNotNull(k2);
            CollectionAssert.AreEqual(new byte[] { 236, 17, 34, 141, 90, 106, 197, 56, 197, 184, 157, 135, 91, 88, 112, 19 }, k2.IV);
            CollectionAssert.AreEqual(new byte[] { 151, 145, 195, 219, 76, 195, 102, 109, 187, 231, 100, 150, 132, 245, 251, 130, 254, 37, 178, 55, 227, 34, 114, 39, 238, 34, 2, 193, 107, 130, 32, 87 }, k2.CipherKey);
            CollectionAssert.AreEqual(new byte[] { 3, 229, 77, 212, 241, 217, 23, 113, 220, 126, 38, 255, 18, 117, 108, 205, 198, 89, 1, 236 }, k2.MacKey);
        }
Beispiel #2
0
        /// <summary>
        ///   Create two streched keys from the shared secret.
        /// </summary>
        /// <remarks>
        ///   The is no spec for this.  Copied https://github.com/libp2p/go-libp2p-crypto/blob/0f79fbebcb64f746a636aba79ece0635ec5919e9/key.go#L183
        /// </remarks>
        public static void Generate(string cipherName, string hashName, byte[] secret, out StretchedKey k1, out StretchedKey k2)
        {
            int cipherKeySize;
            int ivSize;

            switch (cipherName)
            {
            case "AES-128":
                ivSize        = 16;
                cipherKeySize = 16;
                break;

            case "AES-256":
                ivSize        = 16;
                cipherKeySize = 32;
                break;

            case "Blowfish":
                ivSize        = 8;
                cipherKeySize = 32;
                break;

            default:
                throw new NotSupportedException($"Cipher '{cipherName}' is not supported.");
            }
            var hmacKeySize = 20;
            var need        = 2 * (ivSize + cipherKeySize + hmacKeySize);

            var hmac = new HMac(DigestUtilities.GetDigest(hashName));
            var kp   = new KeyParameter(secret);
            var seed = Encoding.ASCII.GetBytes("key expansion");

            hmac.Init(kp);
            var a = new byte[hmac.GetMacSize()];
            var b = new byte[hmac.GetMacSize()];

            hmac.BlockUpdate(seed, 0, seed.Length);
            hmac.DoFinal(a, 0);

            int j      = 0;
            var result = new byte[need];

            while (j < need)
            {
                hmac.Reset();
                hmac.BlockUpdate(a, 0, a.Length);
                hmac.BlockUpdate(seed, 0, seed.Length);
                hmac.DoFinal(b, 0);

                var todo = b.Length;
                if (j + todo > need)
                {
                    todo = need - j;
                }
                Buffer.BlockCopy(b, 0, result, j, todo);
                j += todo;

                hmac.Reset();
                hmac.BlockUpdate(a, 0, a.Length);
                hmac.DoFinal(a, 0);
            }

            int half = need / 2;

            k1 = new StretchedKey
            {
                IV        = new byte[ivSize],
                CipherKey = new byte[cipherKeySize],
                MacKey    = new byte[hmacKeySize]
            };
            Buffer.BlockCopy(result, 0, k1.IV, 0, ivSize);
            Buffer.BlockCopy(result, ivSize, k1.CipherKey, 0, cipherKeySize);
            Buffer.BlockCopy(result, ivSize + cipherKeySize, k1.MacKey, 0, hmacKeySize);

            k2 = new StretchedKey
            {
                IV        = new byte[ivSize],
                CipherKey = new byte[cipherKeySize],
                MacKey    = new byte[hmacKeySize]
            };
            Buffer.BlockCopy(result, half, k2.IV, 0, ivSize);
            Buffer.BlockCopy(result, half + ivSize, k2.CipherKey, 0, cipherKeySize);
            Buffer.BlockCopy(result, half + ivSize + cipherKeySize, k2.MacKey, 0, hmacKeySize);
        }