如何在C#中使用RSA私钥加密数据

时间:2018-08-20 10:05:13

标签: c# .net encryption private-key

我正在使用用Java开发的第三方API。它要求使用给定的RSA私钥加密数据以生成签名。但是C#中的'RSACryptoServiceProvider'仅允许使用公共密钥进行加密。

到目前为止,我已经尝试使用“ BouncyCastle”对带有私钥的数据进行加密。但是API响应出现错误。它说'verify signature failed'

想解决这个问题,有什么主意吗?

顺便说一句: 我使用下面的代码将Java私钥转换为C#xml私钥。这正确吗?

RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(priKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
    Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
    Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
    Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
    Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
    Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
    Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
    Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
    Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));

2 个答案:

答案 0 :(得分:1)

我想您必须使用:

  • 用于解密加密数据或签名数据的私钥,以及
  • 用于加密数据或验证签名的公共密钥。

答案 1 :(得分:0)

在非对称密码术中,使用私钥加密充当签名:每个人都可以验证您是否已使用公钥签名,但只有您可以使用私钥签名(请参见https://en.wikipedia.org/wiki/Public-key_cryptography#Digital_signatures)。 显然,您必须保留一对专用于此目的的密钥。

使用BouncyCastle库,您可以使用RsaEngine实现此结果:

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;    

public void Test()
{
    RsaEngine engine;
    AsymmetricKeyParameter key;
    bool forEncryption;
    int chunkPosition = 0;
    int i = 0;
    int blockSize;
    int chunkSize;
    List<byte> output = new List<byte>();
    byte[] byteMessageArray;


    // Initialize key variable with your public or private key
    // Initialize byteMessageArray with your message to be encrypted or decrypted
    // Set forEncryption variable value 


    engine = new RsaEngine();
    engine.Init(forEncryption, key);
    blockSize = engine.GetInputBlockSize();

    while ((chunkPosition < byteMessageArray.Length))
    {
        chunkSize = Math.Min(blockSize, byteMessageArray.Length - (i * blockSize));
        output.AddRange(engine.ProcessBlock(byteMessageArray, chunkPosition, chunkSize));
        chunkPosition = (chunkPosition + blockSize);
        i += 1;
    }

    //Now in output you have messagge encrypted or decrypted with your private or public key
}