0

I'm working with a third party API which developed in Java. It requires to encrypt data with given RSA private key to generate a signature. But 'RSACryptoServiceProvider' in C# only allow encrypt by a public key.

So far I have tried to use 'BouncyCastle' to encrypt data with a private key. But the API response with an error. It says, 'verify signature failed'.

Hot to fix this, any ideas?

BTW: I use below code to convert Java private key to C# xml private key. Does this correct?

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()));
Super Guo
  • 133
  • 1
  • 1
  • 8
  • 2
    Are you absolutely sure it's "encrypted with the private key"? That sounds quite unusual. – Davesoft Aug 20 '18 at 10:12
  • Yea, I know that not recommend for RSA encrypt. But the third party API that I used, require this step to generate signature. – Super Guo Aug 20 '18 at 10:15
  • 5
    I'm going to arrogantly assume a communication/understanding issue, and suggest you may want to SIGN it rather than encrypt it, which might make this worth reading https://stackoverflow.com/questions/8437288/signing-and-verifying-signatures-with-rsa-c-sharp – Davesoft Aug 20 '18 at 10:18
  • See following line of code [Console.WriteLine("Key is : \n" + rsa.ToXmlString(true));] frommsdn : https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cspparameters?view=netframework-4.7.2 Private key is a unique key which can be randomly generated or from a user input.Most of the MSDN examples uses a random generated private key. MSDN should show examples of user input fixed keys. The following webpage shows had to construct a private key from an integer : https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cspparameters.-ctor?view=netframework-4.7.2 – jdweng Aug 20 '18 at 10:19

2 Answers2

1

I suppose you have to use:

  • a Private Key to decrypt encrypted data or sign data, and
  • a Public Key to encrypt data or verify a signature.
Dim
  • 76
  • 2
0

In asymmetric cryptography, using private key to encrypts acts as a signature: every one can verifies that you had signed using your public key but only you can sign using your private key (see https://en.wikipedia.org/wiki/Public-key_cryptography#Digital_signatures). Obviously you have to keep a pair of keys to be used exclusively for this purpose.

With BouncyCastle library, you can achieve this result using 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
}
hyppos
  • 7
  • 3