簡體   English   中英

為什么 C# 中的 RSA 加密結果與 JavaScript 不同?

[英]Why the result of the RSA encryption in C# is different from JavaScript?

我想運行我的 C# 代碼來登錄 web 站點,所以我需要在 web 站點中實現 RSA 加密方法。 Below is my C# and JavaScript test code to encrypt "test", but they display the different results.How to modify the C# code to get the same result as the JavaScript code?

JavaScript:將代碼保存到html文件中,用web瀏覽器打開即可看到結果。

或者在線運行代碼: https://onlinegdb.com/fzKiCrbGf

它是帶有文檔注釋的 JavaScript RSA 庫: http://www.ohdave.com/rsa/RSA.js

<script src="http://www.ohdave.com/rsa/RSA.js"></script>
<script src="http://www.ohdave.com/rsa/Barrett.js"></script>
<script src="http://www.ohdave.com/rsa/BigInt.js"></script>
<script>
setMaxDigits(130);
var key = new RSAKeyPair("010001","","906C793510FB049452764740B21B97A51DAEA794AB6E43836269D5E6317D49226C12362BA22DAB5EC3BC79553A8A098B01F3C4D81A87B3EE5BD2F4F1431CC495EE2FE54688B212145BB32D56EEEEE1430CE26234331B291CFC53C9B84FAFFDF0B44371A032880C3D567F588D2CD5FCE28D9CDD2923CB547DAD219A6A1B8B5D3D");
var result=encryptedString(key,"test")
document.write(result);
</script>

C#:是C#控制台程序的代碼。運行代碼會看到結果output到控制台。

或者在線運行代碼: https://onlinegdb.com/B1wG_5rXu

class Program
{
    static void Main(string[] args)
    {
        System.Security.Cryptography.RSAParameters rsaParams = new System.Security.Cryptography.RSAParameters
        {
            Modulus = HexToByteArray("906C793510FB049452764740B21B97A51DAEA794AB6E43836269D5E6317D49226C12362BA22DAB5EC3BC79553A8A098B01F3C4D81A87B3EE5BD2F4F1431CC495EE2FE54688B212145BB32D56EEEEE1430CE26234331B291CFC53C9B84FAFFDF0B44371A032880C3D567F588D2CD5FCE28D9CDD2923CB547DAD219A6A1B8B5D3D"),
            Exponent = HexToByteArray("010001"),
        };
        System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider();
        rsa.ImportParameters(rsaParams);
        byte[] result = rsa.Encrypt(System.Text.Encoding.UTF8.GetBytes("test"), false);
        System.Console.Write(ByteArrayToHex(result));
        System.Console.ReadKey();
    }

    public static byte[] HexToByteArray(string hex)
    {
        return Enumerable.Range(0, hex.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                         .ToArray();
    }

    public static string ByteArrayToHex(byte[] ba)
    {
        System.Text.StringBuilder hex = new System.Text.StringBuilder(ba.Length * 2);
        foreach (byte b in ba)
            hex.AppendFormat("{0:x2}", b);
        return hex.ToString();
    }
}

JavaScript 庫默認使用教科書 rsa ,即不應用任何常用(非確定性)填充( PKCS#1 v1.5OAEP )(請注意,JavaScript 庫也支持 PKCS#1 v1.5 填充)
教科書 RSA 是不安全的,因此不應在實踐中使用,如評論中所述,.NET 不支持這種開箱即用的不安全變體,因此必須應用第三方庫。 例如BouncyCastle

此外,JavaScript 庫在內部顛倒了明文的順序,因此必須在 C# 代碼中明確完成。

JavaScript 代碼如下:

 setMaxDigits(130); var key = new RSAKeyPair("010001","","906C793510FB049452764740B21B97A51DAEA794AB6E43836269D5E6317D49226C12362BA22DAB5EC3BC79553A8A098B01F3C4D81A87B3EE5BD2F4F1431CC495EE2FE54688B212145BB32D56EEEEE1430CE26234331B291CFC53C9B84FAFFDF0B44371A032880C3D567F588D2CD5FCE28D9CDD2923CB547DAD219A6A1B8B5D3D"); var result=encryptedString(key,"test") document.write(result);
 <script src="http://www.ohdave.com/rsa/BigInt.js"></script> <script src="http://www.ohdave.com/rsa/Barrett.js"></script> <script src="http://www.ohdave.com/rsa/RSA.js"></script>

產生以下密文:

4331ef280f5fd4f4c53fc2367c90fceb5cc65eca7b343cb5e67c120e4a47202e5343f9b9952f885542053d7c408495a2a3f53da9d13839fcd5b0fc044543ffccd44e8057015534c4ff0f1b849619cf0e5b2c86751c6f6effbc4555158c5000876cc0bb5915abdfbcf211be8a195a97b3fb1662c71a20d8183c589da5a5549b55 

C# 中提供 JavaScript 代碼結果的可能實現是:

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using System;
using System.Text;

...

// Encode plaintext and reverse order
string plaintext = "test";
var dataToEncrypt = Encoding.UTF8.GetBytes(plaintext);
Array.Reverse(dataToEncrypt);

// Import key via modulus and public exponent
string modulus = "906C793510FB049452764740B21B97A51DAEA794AB6E43836269D5E6317D49226C12362BA22DAB5EC3BC79553A8A098B01F3C4D81A87B3EE5BD2F4F1431CC495EE2FE54688B212145BB32D56EEEEE1430CE26234331B291CFC53C9B84FAFFDF0B44371A032880C3D567F588D2CD5FCE28D9CDD2923CB547DAD219A6A1B8B5D3D";
string exponent = "010001";
BigInteger rsaPubMod = new BigInteger(modulus, 16);
BigInteger rsaPubExp = new BigInteger(exponent, 16);
RsaKeyParameters rsaPublic = new RsaKeyParameters(false, rsaPubMod, rsaPubExp);

// Encrypt with NoPadding (= textbook RSA) - Be aware that this is insecure!!!
var cipher = CipherUtilities.GetCipher("RSA/NONE/NoPadding");
cipher.Init(true, rsaPublic);
var encryptedData = cipher.DoFinal(dataToEncrypt);

// Hex encode the data
var encryptedDataHex = BitConverter.ToString(encryptedData).Replace("-", "").ToLower();

Console.WriteLine(encryptedDataHex); // 4331ef280f5fd4f4c53fc2367c90fceb5cc65eca7b343cb5e67c120e4a47202e5343f9b9952f885542053d7c408495a2a3f53da9d13839fcd5b0fc044543ffccd44e8057015534c4ff0f1b849619cf0e5b2c86751c6f6effbc4555158c5000876cc0bb5915abdfbcf211be8a195a97b3fb1662c71a20d8183c589da5a5549b55

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM