Пример #1
0
        private static readonly byte[] DefaultIV = { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 }; // http://www.ietf.org/rfc/rfc3394.txt (see 2.2.3)

        public static byte[] Wrap(byte[] cek, byte[] kek)
        {
            Ensure.MinBitSize(cek, 128, "AesKeyWrap.Wrap() expects content length not less than 128 bits, but was {0}", cek.Length * 8);
            Ensure.Divisible(cek.Length, 8, "AesKeyWrap.Wrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", cek.Length * 8);

            // 1) Initialize variables
            byte[]   a = DefaultIV;                     // Set A = IV, an initial value
            byte[][] r = Arrays.Slice(cek, 8);          // For i = 1 to n
            //     R[0][i] = P[i]
            long n = r.Length;

            // 2) Calculate intermediate values.
            for (long j = 0; j < 6; j++)                                      // For j = 0 to 5
            {
                for (long i = 0; i < n; i++)                                  //    For i=1 to n
                {
                    long t = n * j + i + 1;

                    byte[] b = AesEnc(kek, Arrays.Concat(a, r[i]));     //      B=AES(K, A | R[i])
                    a    = Arrays.FirstHalf(b);                         //      A=MSB(64,B) ^ t where t = (n*j)+i
                    r[i] = Arrays.SecondHalf(b);                        //      R[i] = LSB(64, B)

                    a = Arrays.Xor(a, t);
                }
            }
            // 3) Output the results
            byte[][] c = new byte[n + 1][];
            c[0] = a;                                     //  Set C[0] = A
            for (long i = 1; i <= n; i++)                 //  For i = 1 to n
            {
                c[i] = r[i - 1];                          //     C[i] = R[i]
            }
            return(Arrays.Concat(c));
        }
Пример #2
0
        public static byte[] Wrap(byte[] cek, byte[] kek)
        {
            Ensure.MinBitSize(cek, 128, "AesKeyWrap.Wrap() expects content length not less than 128 bits, but was {0}", new object[] { (int)cek.Length * 8 });
            Ensure.Divisible((int)cek.Length, 8, "AesKeyWrap.Wrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", new object[] { (int)cek.Length * 8 });
            byte[]   defaultIV = AesKeyWrap.DefaultIV;
            byte[][] numArray  = Arrays.Slice(cek, 8);
            long     length    = (long)((int)numArray.Length);

            for (long i = (long)0; i < (long)6; i += (long)1)
            {
                for (long j = (long)0; j < length; j += (long)1)
                {
                    long   num       = length * i + j + (long)1;
                    byte[] numArray1 = AesKeyWrap.AesEnc(kek, Arrays.Concat(new byte[][] { defaultIV, numArray[checked (j)] }));
                    defaultIV             = Arrays.FirstHalf(numArray1);
                    numArray[checked (j)] = Arrays.SecondHalf(numArray1);
                    defaultIV             = Arrays.Xor(defaultIV, num);
                }
            }
            byte[][] numArray2 = new byte[checked (length + 1)][];
            numArray2[0] = defaultIV;
            for (long k = (long)1; k <= length; k += (long)1)
            {
                numArray2[checked (k)] = numArray[checked (k - (long)1)];
            }
            return(Arrays.Concat(numArray2));
        }
        public byte[][] WrapNewKey(int cekSizeBits, object key, IDictionary <string, object> header)
        {
            var sharedPassphrase = Ensure.Type <string>(key, "Pbse2HmacShaKeyManagementWithAesKeyWrap management algorithm expectes key to be string.");

            byte[] sharedKey = Encoding.UTF8.GetBytes(sharedPassphrase);
            byte[] algId     = Encoding.UTF8.GetBytes((string)header["alg"]);

            int iterationCount = 8192;

            byte[] saltInput = Arrays.Random(96); //12 bytes

            header["p2c"] = iterationCount;
            header["p2s"] = Base64Url.Encode(saltInput);

            byte[] salt = Arrays.Concat(algId, Arrays.Zero, saltInput);

            byte[] kek;

            using (var prf = PRF)
            {
                kek = PBKDF2.DeriveKey(sharedKey, salt, iterationCount, keyLengthBits, prf);
            }

            return(aesKW.WrapNewKey(cekSizeBits, kek, header));
        }
        public byte[] Unwrap(byte[] encryptedCek, object key, int cekSizeBits, IDictionary <string, object> header)
        {
            var sharedPassphrase = Ensure.Type <string>(key, "Pbse2HmacShaKeyManagementWithAesKeyWrap management algorithm expectes key to be string.");

            byte[] sharedKey = Encoding.UTF8.GetBytes(sharedPassphrase);

            Ensure.Contains(header, new[] { "p2c" }, "Pbse2HmacShaKeyManagementWithAesKeyWrap algorithm expects 'p2c' param in JWT header, but was not found");
            Ensure.Contains(header, new[] { "p2s" }, "Pbse2HmacShaKeyManagementWithAesKeyWrap algorithm expects 'p2s' param in JWT header, but was not found");

            byte[] algId          = Encoding.UTF8.GetBytes((string)header["alg"]);
            int    iterationCount = Convert.ToInt32(header["p2c"]);

            byte[] saltInput = Base64Url.Decode((string)header["p2s"]);

            byte[] salt = Arrays.Concat(algId, Arrays.Zero, saltInput);

            byte[] kek;

            using (var prf = PRF)
            {
                kek = PBKDF2.DeriveKey(sharedKey, salt, iterationCount, keyLengthBits, prf);
            }

            return(aesKW.Unwrap(encryptedCek, kek, cekSizeBits, header));
        }
Пример #5
0
        public static byte[] Unwrap(byte[] encryptedCek, byte[] kek)
        {
            Ensure.MinBitSize(encryptedCek, 128, "AesKeyWrap.Unwrap() expects content length not less than 128 bits, but was {0}", new object[] { (int)encryptedCek.Length * 8 });
            Ensure.Divisible((int)encryptedCek.Length, 8, "AesKeyWrap.Unwrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", new object[] { (int)encryptedCek.Length * 8 });
            byte[][] numArray  = Arrays.Slice(encryptedCek, 8);
            byte[]   numArray1 = numArray[0];
            byte[][] numArray2 = new byte[(int)numArray.Length - 1][];
            for (int i = 1; i < (int)numArray.Length; i++)
            {
                numArray2[i - 1] = numArray[i];
            }
            long length = (long)((int)numArray2.Length);

            for (long j = (long)5; j >= (long)0; j -= (long)1)
            {
                for (long k = length - (long)1; k >= (long)0; k -= (long)1)
                {
                    long num = length * j + k + (long)1;
                    numArray1 = Arrays.Xor(numArray1, num);
                    byte[] numArray3 = AesKeyWrap.AesDec(kek, Arrays.Concat(new byte[][] { numArray1, numArray2[checked (k)] }));
                    numArray1 = Arrays.FirstHalf(numArray3);
                    numArray2[checked (k)] = Arrays.SecondHalf(numArray3);
                }
            }
            if (!Arrays.ConstantTimeEquals(AesKeyWrap.DefaultIV, numArray1))
            {
                throw new IntegrityException("AesKeyWrap integrity check failed.");
            }
            return(Arrays.Concat(numArray2));
        }
Пример #6
0
 private static byte[] securedInput(byte[] header, byte[] payload, bool b64)
 {
     return(b64
         ? Encoding.UTF8.GetBytes(Compact.Serialize(header, payload))
         : Arrays.Concat(Encoding.UTF8.GetBytes(Compact.Serialize(header)),
                         Encoding.UTF8.GetBytes("."),
                         payload));
 }
Пример #7
0
        private byte[] ComputeAuthTag(byte[] aad, byte[] iv, byte[] cipherText, byte[] hmacKey)
        {
            byte[] al        = Arrays.LongToBytes(aad.Length * 8);
            byte[] hmacInput = Arrays.Concat(aad, iv, cipherText, al);

            byte[] hmac = hashAlgorithm.Sign(hmacInput, hmacKey);

            return(Arrays.FirstHalf(hmac));
        }
Пример #8
0
 private static byte[] F(byte[] salt, int iterationCount, int blockIndex, HMAC prf)
 {
     byte[] numArray  = prf.ComputeHash(Arrays.Concat(new byte[][] { salt, Arrays.IntToBytes(blockIndex) }));
     byte[] numArray1 = numArray;
     for (int i = 2; i <= iterationCount; i++)
     {
         numArray  = prf.ComputeHash(numArray);
         numArray1 = Arrays.Xor(numArray1, numArray);
     }
     return(numArray1);
 }
Пример #9
0
 private byte[] DeriveKey(IDictionary <string, object> header, int cekSizeBits, CngKey externalPublicKey, CngKey privateKey)
 {
     byte[] bytes     = Encoding.UTF8.GetBytes((string)header[this.algIdHeader]);
     byte[] numArray  = (header.ContainsKey("apv") ? Base64Url.Decode((string)header["apv"]) : Arrays.Empty);
     byte[] numArray1 = (header.ContainsKey("apu") ? Base64Url.Decode((string)header["apu"]) : Arrays.Empty);
     byte[] numArray2 = Arrays.Concat(new byte[][] { Arrays.IntToBytes((int)bytes.Length), bytes });
     byte[] numArray3 = Arrays.Concat(new byte[][] { Arrays.IntToBytes((int)numArray1.Length), numArray1 });
     byte[] numArray4 = Arrays.Concat(new byte[][] { Arrays.IntToBytes((int)numArray.Length), numArray });
     byte[] bytes1    = Arrays.IntToBytes(cekSizeBits);
     return(ConcatKDF.DeriveKey(externalPublicKey, privateKey, cekSizeBits, numArray2, numArray4, numArray3, bytes1));
 }
Пример #10
0
        private byte[] DeriveKey(IDictionary <string, object> header, int cekSizeBits, CngKey externalPublicKey, CngKey privateKey)
        {
            byte[] enc = Encoding.UTF8.GetBytes((string)header[algIdHeader]);
            byte[] apv = header.ContainsKey("apv") ? Base64Url.Decode((string)header["apv"]) : Arrays.Empty;
            byte[] apu = header.ContainsKey("apu") ? Base64Url.Decode((string)header["apu"]) : Arrays.Empty;

            byte[] algorithmId = Arrays.Concat(Arrays.IntToBytes(enc.Length), enc);
            byte[] partyUInfo  = Arrays.Concat(Arrays.IntToBytes(apu.Length), apu);
            byte[] partyVInfo  = Arrays.Concat(Arrays.IntToBytes(apv.Length), apv);
            byte[] suppPubInfo = Arrays.IntToBytes(cekSizeBits);

            return(ConcatKDF.DeriveKey(externalPublicKey, privateKey, cekSizeBits, algorithmId, partyVInfo, partyUInfo, suppPubInfo));
        }
Пример #11
0
        private static byte[] F(byte[] salt, int iterationCount, int blockIndex, HMAC prf)
        {
            byte[] U      = prf.ComputeHash(Arrays.Concat(salt, Arrays.IntToBytes(blockIndex))); // U_1 = PRF (P, S || INT (i))
            byte[] result = U;

            for (int i = 2; i <= iterationCount; i++)
            {
                U      = prf.ComputeHash(U);                                                // U_c = PRF (P, U_{c-1}) .
                result = Arrays.Xor(result, U);                                             // U_1 \xor U_2 \xor ... \xor U_c
            }

            return(result);
        }
Пример #12
0
        private static IntPtr ImportKey(IntPtr hAlg, byte[] key, out IntPtr hKey)
        {
            int    num    = BitConverter.ToInt32(AesGcm.GetProperty(hAlg, BCrypt.BCRYPT_OBJECT_LENGTH), 0);
            IntPtr intPtr = Marshal.AllocHGlobal(num);

            byte[] numArray = Arrays.Concat(new byte[][] { BCrypt.BCRYPT_KEY_DATA_BLOB_MAGIC, BitConverter.GetBytes(1), BitConverter.GetBytes((int)key.Length), key });
            uint   num1     = BCrypt.BCryptImportKey(hAlg, IntPtr.Zero, BCrypt.BCRYPT_KEY_DATA_BLOB, out hKey, intPtr, num, numArray, (int)numArray.Length, 0);

            if (num1 != 0)
            {
                throw new CryptographicException(string.Format("BCrypt.BCryptImportKey() failed with status code:{0}", num1));
            }
            return(intPtr);
        }
Пример #13
0
        private static IntPtr ImportKey(IntPtr hAlg, byte[] key, out IntPtr hKey)
        {
            byte[] objLength = GetProperty(hAlg, BCrypt.BCRYPT_OBJECT_LENGTH);

            int keyDataSize = BitConverter.ToInt32(objLength, 0);

            IntPtr keyDataBuffer = Marshal.AllocHGlobal(keyDataSize);

            byte[] keyBlob = Arrays.Concat(BCrypt.BCRYPT_KEY_DATA_BLOB_MAGIC, BitConverter.GetBytes(0x1), BitConverter.GetBytes(key.Length), key);

            uint status = BCrypt.BCryptImportKey(hAlg, IntPtr.Zero, BCrypt.BCRYPT_KEY_DATA_BLOB, out hKey, keyDataBuffer, keyDataSize, keyBlob, keyBlob.Length, 0x0);

            if (status != BCrypt.ERROR_SUCCESS)
            {
                throw new CryptographicException(string.Format("BCrypt.BCryptImportKey() failed with status code:{0}", status));
            }

            return(keyDataBuffer);
        }
Пример #14
0
        public byte[] Unwrap(byte[] encryptedCek, object key, int cekSizeBits, IDictionary <string, object> header)
        {
            byte[] numArray;
            string str = Ensure.Type <string>(key, "Pbse2HmacShaKeyManagementWithAesKeyWrap management algorithm expectes key to be string.", new object[0]);

            byte[] bytes = Encoding.UTF8.GetBytes(str);
            Ensure.Contains(header, new string[] { "p2c" }, "Pbse2HmacShaKeyManagementWithAesKeyWrap algorithm expects 'p2c' param in JWT header, but was not found", new object[0]);
            Ensure.Contains(header, new string[] { "p2s" }, "Pbse2HmacShaKeyManagementWithAesKeyWrap algorithm expects 'p2s' param in JWT header, but was not found", new object[0]);
            byte[] bytes1 = Encoding.UTF8.GetBytes((string)header["alg"]);
            int    num    = Convert.ToInt32(header["p2c"]);

            byte[] numArray1 = Base64Url.Decode((string)header["p2s"]);
            byte[] numArray2 = Arrays.Concat(new byte[][] { bytes1, Arrays.Zero, numArray1 });
            using (HMAC pRF = this.PRF)
            {
                numArray = PBKDF2.DeriveKey(bytes, numArray2, num, this.keyLengthBits, pRF);
            }
            return(this.aesKW.Unwrap(encryptedCek, numArray, cekSizeBits, header));
        }
Пример #15
0
        public byte[][] WrapNewKey(int cekSizeBits, object key, IDictionary <string, object> header)
        {
            byte[] numArray;
            string str = Ensure.Type <string>(key, "Pbse2HmacShaKeyManagementWithAesKeyWrap management algorithm expectes key to be string.", new object[0]);

            byte[] bytes  = Encoding.UTF8.GetBytes(str);
            byte[] bytes1 = Encoding.UTF8.GetBytes((string)header["alg"]);
            int    num    = 8192;

            byte[] numArray1 = Arrays.Random(96);
            header["p2c"] = num;
            header["p2s"] = Base64Url.Encode(numArray1);
            byte[] numArray2 = Arrays.Concat(new byte[][] { bytes1, Arrays.Zero, numArray1 });
            using (HMAC pRF = this.PRF)
            {
                numArray = PBKDF2.DeriveKey(bytes, numArray2, num, this.keyLengthBits, pRF);
            }
            return(this.aesKW.WrapNewKey(cekSizeBits, numArray, header));
        }
Пример #16
0
        public static byte[] DeriveKey(byte[] password, byte[] salt, int iterationCount, int keyBitLength, HMAC prf)
        {
            prf.Key = password;
            ulong num = unchecked ((ulong)-1);

            object[] objArray = new object[] { keyBitLength };
            Ensure.MaxValue(keyBitLength, (long)num, "PBKDF2 expect derived key size to be not more that (2^32-1) bits, but was requested {0} bits.", objArray);
            int hashSize = prf.HashSize / 8;
            int num1     = keyBitLength / 8;
            int num2     = (int)Math.Ceiling((double)num1 / (double)hashSize);
            int num3     = num1 - (num2 - 1) * hashSize;

            byte[][] numArray = new byte[num2][];
            for (int i = 0; i < num2; i++)
            {
                numArray[i] = PBKDF2.F(salt, iterationCount, i + 1, prf);
            }
            numArray[num2 - 1] = Arrays.LeftmostBits(numArray[num2 - 1], num3 * 8);
            return(Arrays.Concat(numArray));
        }
        static byte[] DeriveKey(IDictionary <string, object> header, int cekSizeBits, ECPublicKeyParameters externalPublicKey,
                                ECPrivateKeyParameters ephemeralPrvKey)
        {
            var z = EcdhKeyAgreementZ(externalPublicKey, ephemeralPrvKey);

            var kdfGen = new ConcatenationKdfGenerator(new Sha256Digest());

            byte[] algId = Encoding.ASCII.GetBytes(header["enc"].ToString());
            byte[] apu   = header.ContainsKey("apu") ? Base64Url.Decode((string)header["apu"]) : Arrays.Empty;
            byte[] apv   = header.ContainsKey("apv") ? Base64Url.Decode((string)header["apv"]) : Arrays.Empty;
            byte[] kdl   = CalcBeLengthArray(cekSizeBits);

            var otherInfo = Arrays.Concat(PrependLength(algId), PrependLength(apu), PrependLength(apv), kdl);

            //Console.Out.WriteLine($"otherInfo={VAU.ByteArrayToHexString(otherInfo)}");

            kdfGen.Init(new KdfParameters(z, otherInfo));
            byte[] secretKeyBytes = new byte[32];
            kdfGen.GenerateBytes(secretKeyBytes, 0, secretKeyBytes.Length);
            return(secretKeyBytes);
        }
Пример #18
0
        public static byte[] Unwrap(byte[] encryptedCek, byte[] kek)
        {
            Ensure.MinBitSize(encryptedCek, 128, "AesKeyWrap.Unwrap() expects content length not less than 128 bits, but was {0}", encryptedCek.Length * 8);
            Ensure.Divisible(encryptedCek.Length, 8, "AesKeyWrap.Unwrap() expects content length to be divisable by 8, but was given a content of {0} bit size.", encryptedCek.Length * 8);

            // 1) Initialize variables
            byte[][] c = Arrays.Slice(encryptedCek, 8);
            byte[]   a = c[0];                         //   Set A = C[0]
            byte[][] r = new byte[c.Length - 1][];

            for (int i = 1; i < c.Length; i++)         //   For i = 1 to n
            {
                r[i - 1] = c[i];                       //       R[i] = C[i]
            }
            long n = r.Length;

            // 2) Calculate intermediate values
            for (long j = 5; j >= 0; j--)                                   // For j = 5 to 0
            {
                for (long i = n - 1; i >= 0; i--)                           //   For i = n to 1
                {
                    long t = n * j + i + 1;

                    a = Arrays.Xor(a, t);
                    byte[] B = AesDec(kek, Arrays.Concat(a, r[i]));     //     B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i
                    a    = Arrays.FirstHalf(B);                         //     A = MSB(64, B)
                    r[i] = Arrays.SecondHalf(B);                        //     R[i] = LSB(64, B)
                }
            }

            // 3) Output the results
            if (!Arrays.ConstantTimeEquals(DefaultIV, a))   // If A is an appropriate initial value
            {
                throw new IntegrityException("AesKeyWrap integrity check failed.");
            }

            // For i = 1 to n
            return(Arrays.Concat(r));                        //    P[i] = R[i]
        }
Пример #19
0
        /// <summary>
        /// Implements RFC2898 Password Based Key Derivation Function #2
        /// </summary>
        /// <param name="password">password to be used as hash key</param>
        /// <param name="salt">salt</param>
        /// <param name="iterationCount">number of iterations to perform</param>
        /// <param name="keyBitLength">desired key length in bits to detive</param>
        /// <param name="prf">Pseudo Random Function, HMAC will be inited with key equal to given password</param>
        /// <returns></returns>
        public static byte[] DeriveKey(byte[] password, byte[] salt, int iterationCount, int keyBitLength, HMAC prf)
        {
            prf.Key = password;

            //  1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop.
            Ensure.MaxValue(keyBitLength, 4294967295, "PBKDF2 expect derived key size to be not more that (2^32-1) bits, but was requested {0} bits.", keyBitLength);

            int hLen  = prf.HashSize / 8;                    //size of mac in bytes
            int dkLen = keyBitLength / 8;                    //size of derived key in bytes

            int l = (int)Math.Ceiling(dkLen / (double)hLen); // l = CEIL (dkLen / hLen) ,
            int r = dkLen - (l - 1) * hLen;                  // r = dkLen - (l - 1) * hLen .

            byte[][] T = new byte[l][];

            for (int i = 0; i < l; i++)
            {
                T[i] = F(salt, iterationCount, i + 1, prf);   // T_l = F (P, S, c, l)
            }

            T[l - 1] = Arrays.LeftmostBits(T[l - 1], r * 8);  //truncate last block to r bits

            return(Arrays.Concat(T));                         // DK = T_1 || T_2 ||  ...  || T_l<0..r-1>
        }
 private byte[] ComputeAuthTag(byte[] aad, byte[] iv, byte[] cipherText, byte[] hmacKey)
 {
     byte[] bytes    = Arrays.LongToBytes((long)((int)aad.Length * 8));
     byte[] numArray = Arrays.Concat(new byte[][] { aad, iv, cipherText, bytes });
     return(Arrays.FirstHalf(this.hashAlgorithm.Sign(numArray, hmacKey)));
 }
 static byte[] PrependLength(byte[] data)
 {
     return(Arrays.Concat(CalcBeLengthArray(data.Length), data));
 }