I am trying to sign data on the server side and validate it on the client side. the keys - private and public are saved as PEM strings both on the client (public) and server (private).
When I execute all the actions in the server OR in the client side everything works fine - the signing and verifying.
The code on the server side:
// Prepare data to sign as bytes[]
byte[] dataToSign = Encoding.UTF8.GetBytes(data);
var keyParamAsPEM = (AsymmetricCipherKeyPair)pemReader.ReadObject();
AsymmetricKeyParameter key = keyParamAsPEM.Private;
var keyParameter = new RsaKeyParameters(key.IsPrivate, ((RsaPrivateCrtKeyParameters) key).Modulus, ((RsaPrivateCrtKeyParameters) key).Exponent);
// Init alg
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA");
// Populate key
sig.Init(true, keyParameter);
// Calc signature
sig.BlockUpdate(dataToSign, 0, dataToSign.Length);
byte[] signature = sig.GenerateSignature();
// Base 64 encode the sig so its 8-bit clean
string signatureServer = Convert.ToBase64String(signature);
The code in the client side:
const pubKey = rsa.KEYUTIL.getKey(PUBLIC_KEY);
const rsaObj = new rsa.Signature({ alg: 'SHA256withRSA' });
rsaObj.init(pubKey);
rsaObj.updateString(JSON.stringify(data));
const isValid = rsaObj.verify(signature);
I signed the data in the client side:
const privKey = rsa.KEYUTIL.getKey(PRIVATE_KEY);
const sig = new rsa.Signature({ alg: 'SHA256withRSA' });
sig.init(privKey);
sig.updateString(JSON.stringify(data));
const signatureClient = sig.sign();
And I found out that the signatureClient
(signature created in the client side) is not equal to the signature signed in the signatureServer
(signature created in the server side).
The issue is resolved.
I am using JOSE-JWT dll in the server side, with Bouncy Castle, to sign the data. I create a token while storing the data in the 'sub' property in the claims section.
In the client side I am still using jsrsasign package but I am now verifying the the TOKEN using jws.JWS.verifyJWT()
method.