Exemplo n.º 1
0
        public void DeriveKeyWithString()
        {
            byte[] key            = HexConvertor.GetBytes("1f5942ea0ab514227e339d14743b1df7707a868483725d6166d850d57cd33420");
            byte[] resultOriginal = new byte[124];

            SP800_108.DeriveKey("HMACSHA256", key, derivedOutput: resultOriginal);
        }
Exemplo n.º 2
0
        public void CompareOriginalSha256(string hexKey, string hexLabel, string hexContent, int iterations)
        {
            byte[]      key         = HexConvertor.GetBytes(hexKey);
            byte[]      label       = HexConvertor.GetBytes(hexLabel);
            byte[]      content     = HexConvertor.GetBytes(hexContent);
            Func <HMAC> hmacfactory = () => new HMACSHA256();

            byte[] resultOriginal = new byte[124];
            byte[] resultCustom   = new byte[124];

            SecurityDriven.Inferno.Kdf.SP800_108_Ctr.DeriveKey(hmacfactory,
                                                               key,
                                                               label.Length == 0 ? null : label,
                                                               content.Length == 0 ? null : content,
                                                               resultOriginal,
                                                               (uint)iterations);

            SP800_108.DeriveKey(hmacfactory,
                                key,
                                label.Length == 0 ? Span <byte> .Empty : label,
                                content.Length == 0 ? Span <byte> .Empty : content,
                                resultCustom,
                                (uint)iterations);

            Assert.AreEqual(HexConvertor.GetString(resultOriginal), HexConvertor.GetString(resultCustom));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Unprotect some data with the specified params.
        /// </summary>
        /// <param name="protectedData"></param>
        /// <param name="validationKey"></param>
        /// <param name="decryptionKey"></param>
        /// <param name="decryptionAlgorithmName"></param>
        /// <param name="validationAlgorithmName"></param>
        /// <param name="primaryPurpose"></param>
        /// <param name="specificPurposes"></param>
        /// <returns></returns>
        public static byte[] Unprotect(byte[] protectedData, string validationKey, string decryptionKey, string decryptionAlgorithmName, string validationAlgorithmName, string primaryPurpose, params string[] specificPurposes)
        {
            // The entire operation is wrapped in a 'checked' block because any overflows should be treated as failures.
            checked
            {
                using (SymmetricAlgorithm decryptionAlgorithm = CryptoConfig.CreateFromName(decryptionAlgorithmName) as SymmetricAlgorithm)
                {
                    decryptionAlgorithm.Key = SP800_108.DeriveKey(HexToBinary(decryptionKey), primaryPurpose, specificPurposes);

                    // These KeyedHashAlgorithm instances are single-use; we wrap it in a 'using' block.
                    using (HashAlgorithm validationAlgorithm = CryptoConfig.CreateFromName(validationAlgorithmName) as HashAlgorithm)
                    {
                        if (validationAlgorithm is KeyedHashAlgorithm keydValidationAlgorithm)
                        {
                            keydValidationAlgorithm.Key = SP800_108.DeriveKey(HexToBinary(validationKey), primaryPurpose, specificPurposes);
                        }

                        int ivByteCount               = decryptionAlgorithm.BlockSize / 8;
                        int signatureByteCount        = validationAlgorithm.HashSize / 8;
                        int encryptedPayloadByteCount = protectedData.Length - ivByteCount - signatureByteCount;
                        if (encryptedPayloadByteCount <= 0)
                        {
                            return(null);
                        }

                        byte[] computedSignature = validationAlgorithm.ComputeHash(protectedData, 0, ivByteCount + encryptedPayloadByteCount);

                        if (!BuffersAreEqual(
                                buffer1: protectedData, buffer1Offset: ivByteCount + encryptedPayloadByteCount, buffer1Count: signatureByteCount,
                                buffer2: computedSignature, buffer2Offset: 0, buffer2Count: computedSignature.Length))
                        {
                            return(null);
                        }

                        byte[] iv = new byte[ivByteCount];
                        Buffer.BlockCopy(protectedData, 0, iv, 0, iv.Length);
                        decryptionAlgorithm.IV = iv;

                        using (MemoryStream memStream = new MemoryStream())
                        {
                            using (ICryptoTransform decryptor = decryptionAlgorithm.CreateDecryptor())
                            {
                                using (CryptoStream cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Write))
                                {
                                    cryptoStream.Write(protectedData, ivByteCount, encryptedPayloadByteCount);
                                    cryptoStream.FlushFinalBlock();

                                    byte[] clearData = memStream.ToArray();

                                    return(clearData);
                                }
                            }
                        }
                    }
                }
            }
        }
 public static byte[] Unprotect(byte[] protectedData, string validationKey, string decryptionKey, string decryptionAlgorithmName, string validationAlgorithmName, string primaryPurpose, params string[] specificPurposes)
 {
     using (SymmetricAlgorithm symmetricAlgorithm = CryptoConfig.CreateFromName(decryptionAlgorithmName) as SymmetricAlgorithm)
     {
         symmetricAlgorithm.Key = SP800_108.DeriveKey(HexToBinary(decryptionKey), primaryPurpose, specificPurposes);
         using (KeyedHashAlgorithm keyedHashAlgorithm = CryptoConfig.CreateFromName(validationAlgorithmName) as KeyedHashAlgorithm)
         {
             keyedHashAlgorithm.Key = SP800_108.DeriveKey(HexToBinary(validationKey), primaryPurpose, specificPurposes);
             int blockCount = symmetricAlgorithm.BlockSize / 8;
             int hashCount  = keyedHashAlgorithm.HashSize / 8;
             checked
             {
                 int dataCount = protectedData.Length - blockCount - hashCount;
                 if (dataCount <= 0)
                 {
                     return(null);
                 }
                 byte[] hash = keyedHashAlgorithm.ComputeHash(protectedData, 0, blockCount + dataCount);
                 if (BuffersAreEqual(protectedData, blockCount + dataCount, hashCount, hash, 0, hash.Length))
                 {
                     byte[] iv = new byte[blockCount];
                     Buffer.BlockCopy(protectedData, 0, iv, 0, iv.Length);
                     symmetricAlgorithm.IV = iv;
                     using (MemoryStream memoryStream = new MemoryStream())
                     {
                         using (ICryptoTransform transform = symmetricAlgorithm.CreateDecryptor())
                         {
                             using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write))
                             {
                                 cryptoStream.Write(protectedData, blockCount, dataCount);
                                 cryptoStream.FlushFinalBlock();
                                 return(memoryStream.ToArray());
                             }
                         }
                     }
                 }
                 return(null);
             }
         }
     }
 }
 public AspNetDecryptor(Purpose purpose, CryptographicKey decryptionKey, CryptographicKey validationKey, bool isGzipped)
 {
     this.decryptionKey = SP800_108.DeriveKey(decryptionKey, purpose);
     this.validationKey = SP800_108.DeriveKey(validationKey, purpose);
     this.isGzipped     = isGzipped;
 }
Exemplo n.º 6
0
        /// <summary>
        /// Protect some data with the specified params.
        /// </summary>
        /// <param name="clearData"></param>
        /// <param name="validationKey"></param>
        /// <param name="decryptionKey"></param>
        /// <param name="decryptionAlgorithmName"></param>
        /// <param name="validationAlgorithmName"></param>
        /// <param name="primaryPurpose"></param>
        /// <param name="specificPurposes"></param>
        /// <returns></returns>
        public static byte[] Protect(byte[] clearData, string validationKey, string decryptionKey, string decryptionAlgorithmName, string validationAlgorithmName, string primaryPurpose, params string[] specificPurposes)
        {
            // The entire operation is wrapped in a 'checked' block because any overflows should be treated as failures.
            checked
            {
                // These SymmetricAlgorithm instances are single-use; we wrap it in a 'using' block.
                using (SymmetricAlgorithm encryptionAlgorithm = CryptoConfig.CreateFromName(decryptionAlgorithmName) as SymmetricAlgorithm)
                {
                    // Initialize the algorithm with the specified key and an appropriate IV
                    encryptionAlgorithm.Key = SP800_108.DeriveKey(HexToBinary(decryptionKey), primaryPurpose, specificPurposes);


                    // If the caller didn't ask for a predictable IV, just let the algorithm itself choose one.
                    encryptionAlgorithm.GenerateIV();
                    // IV retrieval
                    byte[] iv = encryptionAlgorithm.IV;

                    using (MemoryStream memStream = new MemoryStream())
                    {
                        memStream.Write(iv, 0, iv.Length);

                        // At this point:
                        // memStream := IV

                        // Write the encrypted payload to the memory stream.
                        using (ICryptoTransform encryptor = encryptionAlgorithm.CreateEncryptor())
                        {
                            using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
                            {
                                cryptoStream.Write(clearData, 0, clearData.Length);
                                cryptoStream.FlushFinalBlock();

                                // At this point:
                                // memStream := IV || Enc(Kenc, IV, clearData)

                                // These KeyedHashAlgorithm instances are single-use; we wrap it in a 'using' block.
                                using (HashAlgorithm signingAlgorithm = CryptoConfig.CreateFromName(validationAlgorithmName) as HashAlgorithm)
                                {
                                    // Initialize the algorithm with the specified key if it's KeyedHashAlgorithm
                                    if (signingAlgorithm is KeyedHashAlgorithm keydSigningAlgorithm)
                                    {
                                        keydSigningAlgorithm.Key = SP800_108.DeriveKey(HexToBinary(validationKey), primaryPurpose, specificPurposes);
                                    }

                                    // Compute the signature
                                    byte[] signature = signingAlgorithm.ComputeHash(memStream.GetBuffer(), 0, (int)memStream.Length);

                                    // At this point:
                                    // memStream := IV || Enc(Kenc, IV, clearData)
                                    // signature := Sign(Kval, IV || Enc(Kenc, IV, clearData))

                                    // Append the signature to the encrypted payload
                                    memStream.Write(signature, 0, signature.Length);

                                    // At this point:
                                    // memStream := IV || Enc(Kenc, IV, clearData) || Sign(Kval, IV || Enc(Kenc, IV, clearData))

                                    // Algorithm complete
                                    byte[] protectedData = memStream.ToArray();
                                    return(protectedData);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 7
0
        static void Main(string[] args)
        {
            string key = null, context = null, label = null;

            string[] labels   = new string[0];
            bool     showhelp = false;

            var p = new OptionSet
            {
                { "k|key=", "the validation key (in hex)", v => key = v },
                { "c|context=", "the context", v => context = v },
                { "l|labels=", "the labels, separated by commas", v => label = v },
                { "h|help", "show this message and exit", v => showhelp = v != null },
                { "?", "show this message and exit", v => showhelp = v != null }
            };

            try {
                p.Parse(args).FirstOrDefault();
            } catch (OptionException ex) {
                Console.Error.Write("ERROR: invalid argument, ");
                Console.Error.WriteLine(ex.Message);
                Console.Error.WriteLine();
                showhelp = true;
            }
            if (!showhelp && key == null)
            {
                Console.Error.WriteLine("ERROR: the key is missing");
                Console.Error.WriteLine();
                showhelp = true;
            }
            if (label != null)
            {
                labels = label.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            }
            if (!showhelp && context == null)
            {
                Console.Error.WriteLine("ERROR: the context is missing");
                Console.Error.WriteLine();
                showhelp = true;
            }
            if (showhelp)
            {
                ShowHelp(p);
                return;
            }

            Debug.Assert(context != null);
            Debug.Assert(key != null);


            if (key.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
            {
                key = key.Substring(2);
            }

            var purpose  = new Purpose(context, labels);
            var keyBytes = CryptoUtil.HexToBinary(key);

            if (keyBytes == null)
            {
                Console.Error.WriteLine("ERROR: the key is invalid");
                Console.Error.WriteLine();
                return;
            }

            Console.WriteLine(Hexify.Hex.PrettyPrint(SP800_108.DeriveKey(
                                                         new CryptographicKey(keyBytes), purpose).GetKeyMaterial()));
        }