如何在 C# 中使用 aesKey 和私有证书加密文本?

How can I encrypt text with aesKey and private cert in C#?

我使用 openSsl 工具创建了 public 和私钥 (pem)。我使用了命令:

openssl genrsa -out privatekey.pem 2048

openssl req -new -key privatekey.pem -x509 -days 3650 -out publiccert.pem

然后我生成 aesKey:

byte[] GenerateAesKey()
{
    var rnd = new RNGCryptoServiceProvider();
    var b = new byte[16];
    rnd.GetNonZeroBytes(b);

    return b;
}

我加密数据的方法:

string CreateSecurePayload(byte[] aesKey)
{
    object obj = new
    {
        contact = new
        {
            email = "myName@email.com",
            firstName = "John",
            lastName = "Doe"
        }
    };

    var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);

    var res = "";

    using (Aes myRijndael = Aes.Create())
    {
        byte[] encrypted = EncryptStringToBytes(json, aesKey, myRijndael.IV);
        res = Convert.ToBase64String(encrypted);
    }
    return res;
}

byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
    byte[] encrypted;

        using (Aes rijAlg = Aes.Create())
        {
            rijAlg.Key = Key;
            rijAlg.IV = IV;

            ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }

        return encrypted;
}

然后我用私钥加密我的 aesKey:

string SecureKey(byte[] aesKey)
    {
        byte[] plainTextBytes = aesKey;

        AsymmetricCipherKeyPair keys;

        FileStream fileStream = new FileStream("path/to/privatekey.pem", FileMode.Open);
        using (var reader = new StreamReader(fileStream))
        {
            var pr = new PemReader(reader);

            keys = (AsymmetricCipherKeyPair)pr.ReadObject();
        }

        var eng = new OaepEncoding(new RsaEngine());
        eng.Init(true, keys.Private);

        int length = plainTextBytes.Length;
        int blockSize = eng.GetInputBlockSize();
        var cipherTextBytes = new List<byte>();
        for (int chunkPosition = 0;
            chunkPosition < length;
            chunkPosition += blockSize)
        {
            int chunkSize = Math.Min(blockSize, length - chunkPosition);
            cipherTextBytes.AddRange(eng.ProcessBlock(
                plainTextBytes, chunkPosition, chunkSize
            ));
        }
        return Convert.ToBase64String(cipherTextBytes.ToArray());
    }

调用方式:

void Main() 
{
    var aesKey = GenerateAesKey();
        
    var encryptData = Newtonsoft.Json.JsonConvert.SerializeObject(new
    {
        securePayload = CreateSecurePayload(aesKey),
        secureKey = SecureKey(aesKey)
    });
}

我有问题。服务不使用 public 密钥解密我的数据。我在服务早期上传 public 密钥。

你能帮帮我吗?谢谢

我有一些关于如何加密数据的示例,但使用的是其他语言:

我得到了 example,但是在 JS 上。我觉得我的 IV 有问题,因为我不发送它

这是帮助您执行Encryption/Decryption的class:

public static class DecryptionHelper
{
    private static string EncryptionDecryptionKey = "your_key";

    public static string Encrypt(string Text)
    {
        //var key = GenerateKey();
        var key = Encoding.UTF8.GetBytes(EncryptionDecryptionKey);

        var plainText = Text;
        var encryptedData = EncryptStringToBytes(key, plainText);

        return Convert.ToBase64String(encryptedData);
    }

    public static string Decrypt(string Text)
    {
        //var key = GenerateKey();
        var key = Encoding.UTF8.GetBytes(EncryptionDecryptionKey);

        byte[] encryptedData = Convert.FromBase64String(Text);
        var decryptedData = DecryptBytesToString(key, encryptedData);

        return decryptedData;
    }

    private static string DecryptBytesToString(byte[] key, byte[] data)
    {
        // IV was prepended to the encrypted bytes so peel that off
        Tuple<byte[], byte[]> splitResult = SplitByteArray(data);
        byte[] iv = splitResult.Item1;
        byte[] cipherText = splitResult.Item2;

        // Declare the string used to hold the decrypted text. 
        string plaintext;

        // Create an RijndaelManaged object 
        // with the specified key and IV. 
        using (var aes = CreateAes256Algorithm())
        {
            aes.Key = key;
            aes.IV = iv;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

            // Create the streams used for decryption. 
            using (var msDecrypt = new MemoryStream(cipherText))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (var srDecrypt = new StreamReader(csDecrypt))
                    {
                        // Read the decrypted bytes from the decrypting stream 
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
        }
        return plaintext;
    }

    private static Tuple<byte[], byte[]> SplitByteArray(byte[] data)
    {
        byte[] first = new byte[16];
        Buffer.BlockCopy(data, 0, first, 0, first.Length);
        byte[] second = new byte[data.Length - first.Length];
        Buffer.BlockCopy(data, first.Length, second, 0, second.Length);
        return Tuple.Create(first, second);
    }

    private static byte[] GenerateKey()
    {
        using (var aes = CreateAes256Algorithm())
        {
            aes.GenerateKey();
            return aes.Key;
        }
    }

    private static RijndaelManaged CreateAes256Algorithm()
    {
        return new RijndaelManaged { KeySize = 256, BlockSize = 128 };
    }

    private static byte[] EncryptStringToBytes(byte[] key, string plainText)
    {
        byte[] encrypted;
        byte[] iv;

        // Create an RijndaelManaged object with the specified key and IV. 
        using (var aes = CreateAes256Algorithm())
        {
            aes.Key = key;
            aes.GenerateIV();

            iv = aes.IV;

            // Create a encrytor to perform the stream transform.
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

            // Create the streams used for encryption. 
            using (var msEncrypt = new MemoryStream())
            {
                using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (var swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                    // convert stream to bytes
                    encrypted = msEncrypt.ToArray();
                }
            }
        }

        // Prepend the iV to the encrypted bytes
        return CombineByteArrays(iv, encrypted);
    }

    private static byte[] CombineByteArrays(byte[] first, byte[] second)
    {
        byte[] ret = new byte[first.Length + second.Length];
        Buffer.BlockCopy(first, 0, ret, 0, first.Length);
        Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
        return ret;
    }
}

然后像这样使用它:

Keys.FacebookClientId = DecryptionHelper.Decrypt(FacebookClientId);
using System;
using System.Text;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Encodings;
using System.Security.Cryptography;
using System.IO;

public static string CreateSecureLoad(string unencryptedPayload, ref byte[] generatedAesKey)
{
// This method generates and returns a secure payload ​
    RijndaelManaged cryptoAlgo = new RijndaelManaged
    {
        Padding = PaddingMode.PKCS7,
        Mode = CipherMode.ECB,
        KeySize = 128,
        BlockSize = 128
    };​
         generatedAesKey = cryptoAlgo.Key;
         var clearTextArray = Encoding.UTF8.GetBytes(unencryptedPayload);
         var encryptor = cryptoAlgo.CreateEncryptor();​
         using (MemoryStream msEncrypt = new MemoryStream())
         {
             using (CryptoStream csEncrypt = new CryptoStream(
                 msEncrypt,
                 encryptor,
                 CryptoStreamMode.Write))
             {
                 csEncrypt.Write(clearTextArray);
                 csEncrypt.FlushFinalBlock();
                 var cipher = msEncrypt.ToArray();
                 return Convert.ToBase64String(cipher);
             }
         }
     }
    
public static string CreateSecureKey(byte[] aesKey, string privateKeyPEM)
     {
         // This method generates and returns a secure key
         // Accepts the string contents of the private key PEM file as input
 ​
         var encryptEngine = new Pkcs1Encoding(new RsaEngine());
 ​
         using (var textReader = new StringReader(privateKeyPEM))
         {
             var pemReader = new PemReader(textReader);
             var keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
             encryptEngine.Init(true, keyPair.Private);
         }
 ​
         var encrypted = Convert.ToBase64String(
             encryptEngine.ProcessBlock(
                 aesKey,
                 0,
                 aesKey.Length));
         return encrypted;
     }
    
static void Main(string[] args)
     {
         String payload = "some json";
 ​
         byte[] generatedAesKey = new byte[16];
         var privateKeyPEM = File.ReadAllText("privatekey.pem");
 ​
         var securePayload = CreateSecureLoad(payload, ref generatedAesKey);
         var secureKey = CreateSecureKey(generatedAesKey, privateKeyPEM);
 ​
         // Return encrypted key
         Console.WriteLine("secureKey: " + secureKey);
 ​
         // Return encrypted payload
         Console.WriteLine("securePayload: " + securePayload);​
         Console.ReadLine();​
     }
 }