static void Main(string[] args) { // setup var rng = new RNGCryptoServiceProvider(); var sslProtect = new OpenSSLProtectData(rng); var sshProtect = new SSHProtectData(rng, sslProtect); // generate SSH keypair var keyPair = OpenSSHKeygen.GenerateKeyPair(); // generate single 32 byte key for aes var symmetricKey = new byte[32]; rng.GetNonZeroBytes(symmetricKey); // some random json string var plainText = "{\"id\":\"some_id\",\"debugging\":false,\"redis\":{\"host\":\"localhost\",\"port\":6379,\"password\":\"passy\",\"db\":0,\"channelPrefix\":null},\"http\":{\"port\":8080},\"ws\":{\"keepalive\":true,\"keepaliveInterval\":30000},\"clientId\":\"some_id\",\"clientSecret\":\"some_secret\"}"; // flip this to use the same symmetricKey (generated above) // or generate a new symmetric key every time // when the same key is used there doesn't seem to be any problems bool useSameKey = false; // loop multiple encryptions and count failures var failures = 0; for (var i = 0; i < 50; i++) { if (!EncryptDecrypt(sshProtect, keyPair, plainText, useSameKey ? symmetricKey : null)) { failures++; } } Console.WriteLine($"Total Failures: {failures}"); }
// encrypt with C# // attempt decrypt with openssl command-line process static bool EncryptDecrypt(SSHProtectData sshProtect, RSAParameters keyPair, String plainText, byte[] symmetricKey) { // separate publicKey components var publicKey = new RSAParameters() { Exponent = keyPair.Exponent, Modulus = keyPair.Modulus }; String encryptedText; byte[] encryptedKey; if (symmetricKey == null) { // produce a new symmetricKey each time // plainText is encrypted with symmetricKey via AES. resulting encryptedText is base64 encoded // symmetricKey is encrypted via RSA with publicKey, producing encryptedKey (encryptedText, symmetricKey, encryptedKey) = sshProtect.Encrypt(plainText, publicKey); } else { // same process as above except using provided symmetricKey instead of generating new one encryptedKey = sshProtect.EncryptSymmetricKey(symmetricKey, keyPair); encryptedText = sshProtect.EncryptWithKey(plainText, symmetricKey); } /* * Console.WriteLine("\n\n\n\n"); * Console.WriteLine($"PlainText: {plainText}\nEncryptedText: {encryptedText}"); * Console.WriteLine($"SymmetricKey: {Convert.ToBase64String(symmetricKey)}"); * Console.WriteLine($"EncryptedKey: {Convert.ToBase64String(encryptedKey)}"); * Console.WriteLine("\n\n\n\n"); */ // writing all files to tmp files for easy usage in openssl cli // write SSH private key for openssl input var privateKeyFile = Path.GetTempFileName(); File.WriteAllText(privateKeyFile, OpenSSHKeygen.ExportPrivateKeyPKCS1(keyPair)); // write encryptedKey for openssl input var encryptedKeyFile = Path.GetTempFileName(); using (var writer = new BinaryWriter(File.Open(encryptedKeyFile, FileMode.Open))) { writer.Write(encryptedKey, 0, encryptedKey.Length); } // write encryptedText for openssl input var encryptedTextFile = Path.GetTempFileName(); File.WriteAllText(encryptedTextFile, encryptedText); var(symmetricKeyFile, decryptKeyCmd) = DecryptSymmetricKeyWithOpenSSL(privateKeyFile, encryptedKeyFile); var(plainTextFile, decryptTextCmd) = DecryptTextWithOpenSSL(encryptedTextFile, symmetricKeyFile); var encryptionSuccess = String.Equals(File.ReadAllText(plainTextFile), plainText); if (!encryptionSuccess) { Console.WriteLine("!!!!FAILED!!!!"); Console.WriteLine($"Ran: {decryptKeyCmd}"); Console.WriteLine($"Ran: {decryptTextCmd}"); // attempt to decrypt the with C# methods var csharpPlainText = sshProtect.Decrypt(encryptedText, encryptedKey, keyPair); if (!String.Equals(csharpPlainText, plainText)) { // never happens Console.WriteLine("C# failed to decrypt"); } // test the raw symmetric key we used to encrypt data in C# // against the symmetric key obtained when openssl decrypted the key using (var reader = new BinaryReader(File.Open(symmetricKeyFile, FileMode.Open))) { var symmetricBytes = new List <byte>(symmetricKey.Length); while (reader.BaseStream.Position < reader.BaseStream.Length) { symmetricBytes.Add(reader.ReadByte()); } if (!symmetricBytes.SequenceEqual(symmetricKey)) { Console.WriteLine("The keys don't match!!"); } // if the above never fires, that means the symmetric key is coming through a-ok } } return(encryptionSuccess); }