简体   繁体   English

JavaScript中的加密不会在C#中解密

[英]Encrypt in JavaScript will not decrypt in C#

I am trying to use RSA encryption in JavaScript and then decrypt it in C#. 我试图在JavaScript中使用RSA加密,然后在C#中解密它。 In JavaScript I am using the library jsencrypt. 在JavaScript中我使用的是库jsencrypt。 In C# I using the API "bouncy castle". 在C#中我使用API​​“充气城堡”。 When I do the encryption/decryption within the same language everything works. 当我在同一种语言中进行加密/解密时,一切正常。 I get back the correct text when I decrypt it. 当我解密它时,我得到了正确的文本。 When I try to decrypt in C# what was encrypted in JavaScript I get nothing close. 当我尝试在C#中解密用JavaScript加密的东西时,我什么都没有得到。 I am sure the keys are the same between the two. 我确信两者之间的关键是相同的。 An example of the code is below. 代码示例如下。 Any help on how to solve this would be greatly appreciated. 任何有关如何解决这个问题的帮助将不胜感激。

JavaScript JavaScript的

//using jsencrypt.min.js

var encrypt = new JSEncrypt();
encrypt.setPublicKey($('#pubkey').val());
var encrypted = encrypt.encrypt($('#input').val());

take the value I get from JavaScript "encrypted" and use it in C# for "encyp" 从JavaScript“加密”获取我得到的值并在C#中用于“encyp”

    AsymmetricCipherKeyPair KeyParameterPrivate;
        byte[] cipheredBytes = Convert.FromBase64String(encyp);


        string privateKeyFileName = @"C:\private.pem";
        using (var fileStream2 = File.OpenText(privateKeyFileName))
        {
            PemReader pemReader2 = new Org.BouncyCastle.OpenSsl.PemReader(fileStream2);
            KeyParameterPrivate = (Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair)pemReader2.ReadObject();
        }
        IAsymmetricBlockCipher cipher2 = new Org.BouncyCastle.Crypto.Engines.RsaEngine();
        RsaKeyParameters privateKey2 = (RsaKeyParameters)KeyParameterPrivate.Private;
        //cipher.Init(false, publicKey4);
        cipher2.Init(false, privateKey2);
        byte[] deciphered = cipher2.ProcessBlock(cipheredBytes, 0, cipheredBytes.Length);
        string decipheredText = utf8enc.GetString(deciphered);

My advice is to keep it as simple as possible and not use Bouncy Castle for this. 我的建议是尽可能保持简单,不要使用Bouncy Castle。 You need to create a public key for encryption, private key for decryption and a certificate to fetch the private key from. 您需要创建用于加密的公钥,用于解密的私钥以及用于从中获取私钥的证书。

First, create private key and certificate PEM files using OpenSSL : 首先,使用OpenSSL创建私钥和证书PEM文件:

openssl req -newkey rsa:1024 -nodes -keyout private_key.pem -x509 -days 365 -out certificate.pem

Then create a public key PEM file from the certificate that you created: 然后从您创建的证书创建公钥PEM文件:

openssl x509 -pubkey -noout -in certificate.pem > public_key.pem

Then export a PFX file using the private key and certificate PEM files that you created: 然后使用您创建的私钥和证书PEM文件导出PFX文件:

openssl pkcs12 -export -out certificate.pfx -inkey private_key.pem -in certificate.pem

When you do the export, you'll be asked to provide a certificate password. 执行导出时,系统会要求您提供证书密码。

Now here is how to do the RSA decryption in C#: 现在这里是如何在C#中进行RSA解密:

var cert = new X509Certificate2(@"C:\path\to\certificate.pfx", "password");
var rsaCng = (RSACng)cert.PrivateKey;
var decryptedText = Encoding.UTF8.GetString(rsaCng.Decrypt(Convert.FromBase64String(encryptedText), RSAEncryptionPadding.Pkcs1));

Why would you want to torture yourself using BC for this? 你为什么要用BC来折磨自己呢?

The easiest approach to decryption here is : 这里最简单的解密方法是:

 // store is a X509Store pointing to the correct store on the target machine
 // You have to ensure that the security principal for your app has access to the private key to decrypt
 X509Certificate2 cert = store.Certificates.Find(X509FindType.FindByThumbprint, "sha1hash", false)[0];

 var prov = (RSACryptoServiceProvider)cert.PrivateKey;
 var decipheredText = Encoding.UTF8.GetString(prov.Decrypt(Convert.FromBase64String(target), false));

Obviously you can get your X509Certificate2 from file or any other means, eg X509Certificate2 cert = new X509Certificate2(@"C:\\someCert.pfx", "somePass"); 显然,您可以从文件或任何其他方式获得X509Certificate2,例如X509Certificate2 cert = new X509Certificate2(@"C:\\someCert.pfx", "somePass");

If you followed jsencrypt tutorial, use this openssl command to get the pfx out of the pems you have: 如果您遵循jsencrypt教程,请使用此openssl命令从您拥有的pems中获取pfx:

openssl pkcs12 -export -out certificate.pfx -inkey privateKey.pem -in publicKey.pem

You'll have to use new PKCS1Encoding(cipher2) . 您将不得不使用new PKCS1Encoding(cipher2) The RSAEngine only produces plain (also known as raw or textbook) RSA. RSAEngine仅生成普通(也称为原始或教科书)RSA。

Tell me if it works for you. 告诉我它是否适合你。

public string Decrypt(RSACryptoServiceProvider provider, string toDecrypt)
{
    var input = Convert.FromBase64String(toDecrypt);
    IEnumerable<byte> output = new List<byte>();
    for (var i = 0; i < input.Length; i = i + input.Length)
    {
        var length = Math.Max(input.Length - i, 128);
        var block = new byte[length];
        Buffer.BlockCopy(input, i, block, 0, length);
        var chunk = provider.Decrypt(block, false);
        output = output.Concat(chunk);
    }
    return Encoding.UTF8.GetString(output.ToArray());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM