Ejemplo n.º 1
0
        /// <inheritdoc/>
        public byte[] Unprotect(string protectedData)
        {
            // Extract encrypted key and encrypted data
            string[] parts = protectedData.Split(Separator);
            if (parts.Length != 3)
            {
                throw new Exception("Invalid format of protected data");
            }
            byte[] encryptedStoredKey = CryptoUtils.Base64StringToBytes(parts[0]);
            byte[] nonce             = CryptoUtils.Base64StringToBytes(parts[1]);
            byte[] protectedDataPart = CryptoUtils.Base64StringToBytes(parts[2]);

            // Unprotect the random key with OS support
            byte[] storedKey = null;
            try
            {
                if (KeysExistInKeyStore())
                {
                    Cipher cipher     = Cipher.GetInstance("RSA/ECB/PKCS1Padding"); // ECB mode is not used by RSA
                    IKey   privateKey = GetPrivateKeyFromKeyStore();
                    cipher.Init(CipherMode.DecryptMode, privateKey);
                    storedKey = cipher.DoFinal(encryptedStoredKey);
                }
            }
            catch (Exception)
            {
                storedKey = null;
            }

            // Fallback to obfuscated key
            if (storedKey == null)
            {
                storedKey = CryptoUtils.Deobfuscate(encryptedStoredKey, CryptoUtils.StringToSecureString(Obcake));
            }

            // Decrypt the data with the random key
            ISymmetricEncryptionAlgorithm decryptor;

            byte[] result;
            try
            {
                decryptor = new BouncyCastleXChaCha20();
                result    = decryptor.Decrypt(protectedDataPart, storedKey, nonce);
            }
            catch (Exception)
            {
                // Fallback to twofish, which was used before 3.2021
                decryptor = new BouncyCastleTwofishGcm();
                result    = decryptor.Decrypt(protectedDataPart, storedKey, nonce);
            }
            return(result);
        }
Ejemplo n.º 2
0
        public void EnsureCompatibilityToLibsodiumXChaCha20()
        {
            // Ensure that a once stored cipher can always be decrypted even after changes in the liberary.
            // This cypher was created with libsodium.
            string base64Cipher = "q8w/Zotsi3ZJp2eaAnFmMiAGgko+N2TkNgunS5+bDRNqrBBoN+XMQPSt7ojO4ODMP3Rf3aoYMNeJFL2/ZqK3AngIuQ==";

            byte[] cipher = CryptoUtils.Base64StringToBytes(base64Cipher);

            ISymmetricEncryptionAlgorithm decryptor       = new BouncyCastleXChaCha20();
            ICryptoRandomService          randomGenerator = CommonMocksAndStubs.CryptoRandomService(88);

            byte[] key   = randomGenerator.GetRandomBytes(decryptor.ExpectedKeySize);
            byte[] nonce = randomGenerator.GetRandomBytes(decryptor.ExpectedNonceSize);

            string decryptedMessage = CryptoUtils.BytesToString(decryptor.Decrypt(cipher, key, nonce));

            Assert.AreEqual("The brown fox jumps over the lazy 🐢🖐🏿 doc.", decryptedMessage);
        }