1

I generated a private and public key in javascript like this.

import crypto from "crypto";

/*export const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", {
  modulusLength: 2048,
});*/

const pair = crypto.generateKeyPairSync("rsa", { modulusLength: 2048 });

export const privateKey = pair.privateKey.export({
  type: "pkcs1",
  format: "pem",
});
export const publicKey = pair.publicKey.export({
  type: "pkcs1",
  format: "pem",
});

Then i use the private key to create a signature for a jsonfile like this, and the public key to verify it before i return the signature.

 //Lav signatur
    const signate = crypto.createSign("SHA384");
    signate.update(Buffer.from(licenseRelationship, "utf-8"));
    const signature = signate.sign(privateKey, "hex");
    const verifier = crypto.createVerify("SHA384");

    // verificer signature, besked
    verifier.update(Buffer.from(licenseRelationship, "utf-8"));
    const verificationResult = verifier.verify(publicKey, signature, "hex");

This works perfectly, and then i return the json and the signature as a http response.

I recieve it in c# code and store the two components so im can use them later on request.

Upon request i fetch the two components and want to use the signature to check if the json has been tampered with.

I also has the public key in this code.

I do it like this.

string licenseRelationshipJson = licenseRelationshipDAO.getLicenseRelationshipWithoutSignatureAsJson(licenseRelationship);
byte[] signature = Encoding.UTF8.GetBytes(licenseRelationship.signature);    
byte[] licenseRelationshipJsonAsArray = Encoding.UTF8.GetBytes(licenseRelationshipJson);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
result = rsa.VerifyData(licenseRelationshipJsonAsArray, signature, 
                        HashAlgorithmName.SHA384, RSASignaturePadding.Pkcs1);
if (result)
   {
      log.write("Message verified ", null);
   } else
   {
     log.write("Message not Verified ", null);
   }

All debug code and exception handling removed.

I'm a crypto virgin, and am trying to understand this. But i must have misunderstood something serious.

I have the public key as a string (not base64 encoded) Ive checked the json, and it is the exact same bytes when signed in Javascript as when being verified in c#

The public key is not used in this process. That has to be wrong i think ? How do i get the public key into the RWACryptoServiceProvider ?

Im sure im using RWACryptoServiceProvider wrong.

EDIT....:

Ive tried this instead, but still to no avail.

string licenseRelationshipJson = licenseRelationshipDAO.getLicenseRelationshipWithoutSignatureAsJson(licenseRelationship);
byte[] signature = Encoding.UTF8.GetBytes(licenseRelationship.signature);
byte[] licenseRelationshipJsonAsArray = Encoding.UTF8.GetBytes(licenseRelationshipJson);
byte[] asBytes = Encoding.ASCII.GetBytes(DataStorage.Instance.PUBLIC_KEY);
char[] publicKeyAsArray = Encoding.ASCII.GetChars(asBytes);
            ReadOnlySpan<char> publicKeyChars = publicKeyAsArray;

RSA rsa = RSA.Create();
try
{
  rsa.ImportFromPem(publicKeyChars);
  result = rsa.VerifyData(licenseRelationshipJsonAsArray, signature, HashAlgorithmName.SHA384, RSASignaturePadding.Pkcs1);
} catch (CryptographicException cex)
{
  log.write("Something went wrong with the crypto verification process", cex);
}
.
.
.

Thankyou for your time.

  • 1
    In the NodeJS code the signature is hex encoded. In the C# code, however, the corresponding hex decoding is missing. Instead, the signature is UTF8 encoded, which generally corrupts the data. If I fix this and use my own data and keys, verification with the second C# code snippet works (the first C# code snippet must fail, of course, because the key import is missing, as you already realized). – Topaco Oct 20 '21 at 16:59
  • Thankyou so much, Ill check it out immidiately – Kim Sandberg Oct 21 '21 at 06:44
  • Ive tried the last code snippet with byte[] signature = Encoding.ASCII.GetBytes(licenseRelationship.signature); But still cannot get a true result. Am i encoding the hex wrong ? – Kim Sandberg Oct 21 '21 at 06:55
  • In the NodeJS code, the signature is returned as hex string (`sign(..., "hex")`), so you have to convert it back to a `byte[]` in the C# code, see [here](https://stackoverflow.com/q/321370/9014097). – Topaco Oct 21 '21 at 07:06
  • Yeah i was looking at similar things.... Thankyou for your help and time. It is very much appreciated. – Kim Sandberg Oct 21 '21 at 07:15
  • Thankyou @Topaco that was it.... You made my day. – Kim Sandberg Oct 21 '21 at 07:44

0 Answers0