コード例 #1
0
        public IdentityDataProtectorKeyRing()
        {
            var keyRingDirectory = Path.Combine(Directory.GetCurrentDirectory(), "keyring");

            if (!Directory.Exists(keyRingDirectory))
            {
                Directory.CreateDirectory(keyRingDirectory);
            }

            var directoryInfo = new DirectoryInfo(keyRingDirectory);

            if (directoryInfo.GetFiles("*.key").Length == 0)
            {
                ProtectorAlgorithmHelper.GetAlgorithms(
                    ProtectorAlgorithmHelper.DefaultAlgorithm,
                    out var encryptionAlgorithm,
                    out var signingAlgorithm,
                    out _);
                encryptionAlgorithm.GenerateKey();

                var keyAsString = Convert.ToBase64String(encryptionAlgorithm.Key);
                var keyId       = Guid.NewGuid().ToString();
                var keyFileName = Path.Combine(keyRingDirectory, keyId + ".key");
                using (var file = File.CreateText(keyFileName))
                {
                    file.WriteLine(keyAsString);
                }

                _keyDictionary.Add(keyId, keyAsString);

                CurrentKeyId = keyId;

                encryptionAlgorithm.Clear();
                encryptionAlgorithm.Dispose();
                signingAlgorithm.Dispose();
            }
            else
            {
                var filesOrdered = directoryInfo.EnumerateFiles()
                                   .OrderByDescending(d => d.CreationTime)
                                   .Select(d => d.Name)
                                   .ToList();

                foreach (var fileName in filesOrdered)
                {
                    var keyFileName = Path.Combine(keyRingDirectory, fileName);
                    var key         = File.ReadAllText(keyFileName);
                    var keyId       = Path.GetFileNameWithoutExtension(fileName);
                    _keyDictionary.Add(keyId, key);
                    CurrentKeyId = keyId;
                }
            }
        }
コード例 #2
0
        public string Protect(string data)
        {
            if (string.IsNullOrEmpty(data))
            {
                return(string.Empty);
            }

            ProtectorAlgorithmHelper.GetAlgorithms(
                _defaultAlgorithm,
                out var encryptingAlgorithm,
                out var signingAlgorithm,
                out var keyDerivationIterationCount);

            var blob = new CryptoBlob
            {
                KeyId = _keyRing.CurrentKeyId,
                SymmetricAlgorithmId = (int)_defaultAlgorithm,
                InitializationVector = encryptingAlgorithm.IV
            };

            var masterKey     = GetKey(blob.KeyId);
            var encryptionKey =
                GenerateEncryptionKey(masterKey, encryptingAlgorithm.KeySize, keyDerivationIterationCount);

            encryptingAlgorithm.Key = encryptionKey;

            var encryptedPayload = EncryptData(data, encryptingAlgorithm);

            blob.Payload   = encryptedPayload;
            blob.Signature = GetPayloadSignature(
                encryptedPayload: encryptedPayload,
                iv: encryptingAlgorithm.IV,
                masterKey: masterKey,
                symmetricAlgorithmKeySize: encryptingAlgorithm.KeySize,
                hashAlgorithm: signingAlgorithm,
                keyDerivationIterationCount: keyDerivationIterationCount);

            encryptingAlgorithm.Clear();
            signingAlgorithm.Clear();
            encryptingAlgorithm.Dispose();
            signingAlgorithm.Dispose();

            return(blob.ToBase64());
        }
コード例 #3
0
        public string Unprotect(string data)
        {
            if (string.IsNullOrEmpty(data))
            {
                return(string.Empty);
            }

            var blob = new CryptoBlob(data);

            ProtectorAlgorithmHelper.GetAlgorithms(
                (ProtectorAlgorithm)blob.SymmetricAlgorithmId,
                out var encryptingAlgorithm,
                out var signingAlgorithm,
                out int keyDerivationIterationCount);

            var masterKey     = GetKey(blob.KeyId);
            var decryptionKey =
                GenerateEncryptionKey(masterKey, encryptingAlgorithm.KeySize, keyDerivationIterationCount);

            encryptingAlgorithm.Key = decryptionKey;
            encryptingAlgorithm.IV  = blob.InitializationVector;

            var signature = GetPayloadSignature(blob.Payload,
                                                blob.InitializationVector,
                                                masterKey,
                                                encryptingAlgorithm.KeySize,
                                                signingAlgorithm,
                                                keyDerivationIterationCount);

            if (!ByteArraysEqual(signature, blob.Signature))
            {
                throw new CryptographicException(@"Invalid Signature.");
            }

            var decryptedData = DecryptData(blob.Payload, encryptingAlgorithm);

            encryptingAlgorithm.Clear();
            encryptingAlgorithm.Dispose();

            return(Encoding.UTF8.GetString(decryptedData));
        }
コード例 #4
0
        public string Unprotect(string keyId, string data)
        {
            var masterKey = MasterKey(keyId);

            byte[] plainText;

            // Take our string and convert it back to bytes.
            var payload = Convert.FromBase64String(data);

            // Read the saved algorithm details and create instances of those algorithms.
            byte[] algorithmIdentifierAsBytes = new byte[4];
            Buffer.BlockCopy(payload, 0, algorithmIdentifierAsBytes, 0, 4);
            var algorithmIdentifier = (ProtectorAlgorithm)(BitConverter.ToInt32(algorithmIdentifierAsBytes, 0));

            ProtectorAlgorithmHelper.GetAlgorithms(
                _defaultAlgorithm,
                out SymmetricAlgorithm encryptingAlgorithm,
                out KeyedHashAlgorithm signingAlgorithm,
                out int keyDerivationIterationCount);

            // Now extract the signature
            byte[] signature = new byte[signingAlgorithm.HashSize / 8];
            Buffer.BlockCopy(payload, 4, signature, 0, signingAlgorithm.HashSize / 8);

            // And finally grab the rest of the data
            var dataLength = payload.Length - 4 - signature.Length;

            byte[] cipherTextAndIV = new byte[dataLength];
            Buffer.BlockCopy(payload, 4 + signature.Length, cipherTextAndIV, 0, dataLength);

            // Check the signature before anything else is done to detect tampering and avoid
            // oracles.
            byte[] computedSignature = SignData(
                cipherTextAndIV,
                masterKey,
                encryptingAlgorithm,
                signingAlgorithm,
                keyDerivationIterationCount);
            if (!ByteArraysEqual(computedSignature, signature))
            {
                throw new CryptographicException(@"Invalid Signature.");
            }

            signingAlgorithm.Clear();
            signingAlgorithm.Dispose();

            // The signature is valid, so now we can work on decrypting the data.
            var ivLength = encryptingAlgorithm.BlockSize / 8;

            byte[] initializationVector = new byte[ivLength];
            byte[] cipherText           = new byte[cipherTextAndIV.Length - ivLength];
            // The IV is embedded in the cipher text, so we extract it out.
            Buffer.BlockCopy(cipherTextAndIV, 0, initializationVector, 0, ivLength);
            // Then we get the encrypted data.
            Buffer.BlockCopy(cipherTextAndIV, ivLength, cipherText, 0, cipherTextAndIV.Length - ivLength);

            encryptingAlgorithm.Key = DerivedEncryptionKey(
                masterKey,
                encryptingAlgorithm,
                keyDerivationIterationCount);
            encryptingAlgorithm.IV = initializationVector;

            // Decrypt
            using (var ms = new MemoryStream())
                using (var cs = new CryptoStream(ms, encryptingAlgorithm.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherText);
                    cs.FlushFinalBlock();
                    plainText = ms.ToArray();
                }

            encryptingAlgorithm.Clear();
            encryptingAlgorithm.Dispose();

            // And convert from the bytes back to a string.
            return(Encoding.UTF8.GetString(plainText));
        }
コード例 #5
0
        public string Protect(string keyId, string data)
        {
            // Get the default algorithms.
            // We does this so we can embed the algorithm details used in the cipher text so we can
            // change algorithms as yet another collision appears in a hashing algorithm.
            // See https://media.blackhat.com/bh-us-10/whitepapers/Sullivan/BlackHat-USA-2010-Sullivan-Cryptographic-Agility-wp.pdf
            ProtectorAlgorithmHelper.GetAlgorithms(
                _defaultAlgorithm,
                out SymmetricAlgorithm encryptingAlgorithm,
                out KeyedHashAlgorithm signingAlgorithm,
                out int keyDerivationIterationCount);

            var masterKey = MasterKey(keyId);

            // Convert the string to bytes, because encryption works on bytes, not strings.
            var plainText = Encoding.UTF8.GetBytes(data);

            byte[] cipherTextAndIV;

            // Derive a key for encryption from the master key
            encryptingAlgorithm.Key = DerivedEncryptionKey(
                masterKey,
                encryptingAlgorithm,
                keyDerivationIterationCount);

            // As we need this to be deterministic, we need to force an IV that is derived from the plain text.
            encryptingAlgorithm.IV = DerivedInitializationVector(
                masterKey,
                data,
                encryptingAlgorithm,
                keyDerivationIterationCount);

            // And encrypt
            using (var ms = new MemoryStream())
                using (var cs = new CryptoStream(
                           ms,
                           encryptingAlgorithm.CreateEncryptor(),
                           CryptoStreamMode.Write))
                {
                    cs.Write(plainText);
                    cs.FlushFinalBlock();
                    var encryptedData = ms.ToArray();

                    cipherTextAndIV = CombineByteArrays(encryptingAlgorithm.IV, encryptedData);
                }

            // Now get a signature for the data so we can detect tampering in situ.
            byte[] signature = SignData(
                cipherTextAndIV,
                masterKey,
                encryptingAlgorithm,
                signingAlgorithm,
                keyDerivationIterationCount);

            // Add the signature to the cipher text.
            var signedData = CombineByteArrays(signature, cipherTextAndIV);

            // Add our algorithm identifier to the combined signature and cipher text.
            var algorithmIdentifier = BitConverter.GetBytes((int)_defaultAlgorithm);

            byte[] output = CombineByteArrays(algorithmIdentifier, signedData);

            // Clean everything up.
            encryptingAlgorithm.Clear();
            signingAlgorithm.Clear();
            encryptingAlgorithm.Dispose();
            signingAlgorithm.Dispose();

            Array.Clear(plainText, 0, plainText.Length);

            // Return the results as a string.
            return(Convert.ToBase64String(output));
        }