Validating a JWT in node.js - javascript

I'm trying to parse and validate a JWT token in node.js based on this sample (authored in .NET): https://github.com/liveservices/LiveSDK/blob/master/Samples/Asp.net/AuthenticationTokenSample/JsonWebToken.cs
Here is my node js javascript that validates the token:
var validateSignature = function(key, claims, envelope, signature) {
var hasher = crypto.createHash('sha256');
hasher.update(key + "JWTSig");
var key = hasher.digest('binary');
var hmac = crypto.createHmac('sha256', key);
hmac.update(envelope + '.' + claims);
var out = hmac.digest('base64');
console.log(out);
console.log(signature);
console.log(out === signature);
}
Now, the very weird thing is - it almost works. Here's the output of the three console.log statements:
pEwNPJ+LUHBdvNx631UzdyVhPFUOvFY8jG3x/cP81FE=
pEwNPJ-LUHBdvNx631UzdyVhPFUOvFY8jG3x_cP81FE
false
It seems suspicious to me that the hashes are both the same except for the +-/_=
Anybody spot my mistake? Something to do with my base64 encoding.
UPDATE
I played some more and there seems to be something funky going on with base64 encoding here. The following code in node js:
console.log(signature);
var b = new Buffer(signature, 'base64');
console.log(b.toString('base64'));
yields:
pEwNPJ-LUHBdvNx631UzdyVhPFUOvFY8jG3x_cP81FE
pEwNPJLUHBdvNx631UzdyVhPFUOvFY8jG3xcP81F
Which seems very odd, right?

Thanks to Timothy Meade for commenting and pushing me in the right direction.
Node's Buffer type generates standard Base64 with +, / and =
There is a URL safe base64 encoding as mentioned here: http://en.wikipedia.org/wiki/Base64
It replaces + with -, / with _ and = is optional. The token that is passed on the QueryString (d'uh) is a URL safe version. Hence the difference.
Code was fixed by a simple:
out = out.replace('+','-').replace('/','_').replace('=','');

I wrote this library a while ago, I guess you can use some of the code. It is supposed to run in both node.js and in a modern browser.
JWT library for javascript

This is not the exact method that you were trying to use, but I believe it is the preferred way to validate a JWT in NodeJS. Note that I am using the NPM base64url library to convert between base64Url (the default encoding for a JWT) and base64 (what NodeJS expects for the verification function).
Also note, you need a public and private keypair to sign and verify respectively. I have included the private and public keys that were used to sign and verify this JWT at the bottom of this post.
const base64 = require('base64url');
const crypto = require('crypto');
const verifyFunction = crypto.createVerify('RSA-SHA256');
const fs = require('fs');
// The sample JWT from https://jwt.io/
const JWT = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.POstGetfAytaZS82wHcjoTyoqhMyxXiWdR7Nn7A29DNSl0EiXLdwJ6xC6AfgZWF1bOsS_TuYI3OG85AmiExREkrS6tDfTQ2B3WXlrr-wp5AokiRbz3_oB4OxG-W9KcEEbDRcZc0nH3L7LzYptiy1PtAylQGxHTWZXtGz4ht0bAecBgmpdgXMguEIcoqPJ1n3pIWk_dUZegpqx0Lka21H6XxUTxiy8OcaarA8zdnPUnV6AmNP3ecFawIFYdvJB_cm-GvpCSbr8G8y_Mllj8f4x9nBH8pQux89_6gUY618iYv7tuPWBFfEbLxtF2pZS6YC1aSfLQxeNe8djT9YjpvRZA';
// This just gets the value of the public key (same as the one at bottom of this post)
const PUB_KEY = fs.readFileSync(__dirname + '/id_rsa_pub.pem', 'utf8');
// Split the JWT by `.` to get each part
const jwtHeader = JWT.split('.')[0];
const jwtPayload = JWT.split('.')[1];
const jwtSignature = JWT.split('.')[2];
// We only need the first two pieces to verify
verifyFunction.write(jwtHeader + '.' + jwtPayload);
verifyFunction.end();
// IMPORTANT: NodeJS expects base64 format, not base64url format!
const jwtSignatureBase64 = base64.toBase64(jwtSignature);
// IMPORTANT: You need to specify that the `jwtSignatureBase64` data is base64 format,
// otherwise, it will default to Buffer format and return false
const signatureIsValid = verifyFunction.verify(PUB_KEY, jwtSignatureBase64, 'base64');
console.log(signatureIsValid); // true
The keys below are from the example JWT mentioned here.
Private Key:
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWw
kWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mr
m/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEi
NQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV
3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2
QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQABAoIBACiARq2wkltjtcjs
kFvZ7w1JAORHbEufEO1Eu27zOIlqbgyAcAl7q+/1bip4Z/x1IVES84/yTaM8p0go
amMhvgry/mS8vNi1BN2SAZEnb/7xSxbflb70bX9RHLJqKnp5GZe2jexw+wyXlwaM
+bclUCrh9e1ltH7IvUrRrQnFJfh+is1fRon9Co9Li0GwoN0x0byrrngU8Ak3Y6D9
D8GjQA4Elm94ST3izJv8iCOLSDBmzsPsXfcCUZfmTfZ5DbUDMbMxRnSo3nQeoKGC
0Lj9FkWcfmLcpGlSXTO+Ww1L7EGq+PT3NtRae1FZPwjddQ1/4V905kyQFLamAA5Y
lSpE2wkCgYEAy1OPLQcZt4NQnQzPz2SBJqQN2P5u3vXl+zNVKP8w4eBv0vWuJJF+
hkGNnSxXQrTkvDOIUddSKOzHHgSg4nY6K02ecyT0PPm/UZvtRpWrnBjcEVtHEJNp
bU9pLD5iZ0J9sbzPU/LxPmuAP2Bs8JmTn6aFRspFrP7W0s1Nmk2jsm0CgYEAyH0X
+jpoqxj4efZfkUrg5GbSEhf+dZglf0tTOA5bVg8IYwtmNk/pniLG/zI7c+GlTc9B
BwfMr59EzBq/eFMI7+LgXaVUsM/sS4Ry+yeK6SJx/otIMWtDfqxsLD8CPMCRvecC
2Pip4uSgrl0MOebl9XKp57GoaUWRWRHqwV4Y6h8CgYAZhI4mh4qZtnhKjY4TKDjx
QYufXSdLAi9v3FxmvchDwOgn4L+PRVdMwDNms2bsL0m5uPn104EzM6w1vzz1zwKz
5pTpPI0OjgWN13Tq8+PKvm/4Ga2MjgOgPWQkslulO/oMcXbPwWC3hcRdr9tcQtn9
Imf9n2spL/6EDFId+Hp/7QKBgAqlWdiXsWckdE1Fn91/NGHsc8syKvjjk1onDcw0
NvVi5vcba9oGdElJX3e9mxqUKMrw7msJJv1MX8LWyMQC5L6YNYHDfbPF1q5L4i8j
8mRex97UVokJQRRA452V2vCO6S5ETgpnad36de3MUxHgCOX3qL382Qx9/THVmbma
3YfRAoGAUxL/Eu5yvMK8SAt/dJK6FedngcM3JEFNplmtLYVLWhkIlNRGDwkg3I5K
y18Ae9n7dHVueyslrb6weq7dTkYDi3iOYRW8HRkIQh06wEdbxt0shTzAJvvCQfrB
jg/3747WSsf/zBTcHihTRBdAv6OmdhV4/dD5YBfLAkLrd+mX7iE=
-----END RSA PRIVATE KEY-----
Public Key:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv
vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc
aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy
tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0
e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb
V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9
MwIDAQAB
-----END PUBLIC KEY-----

Related

How to decrypt RSA encrypted string from JavaScript in C#?

I have an asymmetric RSA key pair stored in two separate files. I want to generate a new symmetric key and encrypt it with public RSA key in my postbuild.js GULP script, so the user cannot access it. Then I want to send it to the C# server, where it would be decrypted and used.
I use the following JavaScript code in Node.js for encryption:
const generateAndEncryptKey = () => {
const symmetricKey = crypto.randomBytes(32);
const publicKey = fs.readFileSync("pubkey.pem", "utf8");
const encryptedSymmetricKey = crypto.publicEncrypt({
key: publicKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: "sha256",
}, Buffer.from(symmetricKey)).toString("base64");
return encryptedSymmetricKey;
}
The above code somehow works and generates a base64 string that I later send to the server. I'm not sure if this is the correct way to do this.
But I'm unable to find a way to decrypt this string in C#. I tried to use the BouncyCastle library and the following code:
public string DecryptKey(string encryptedKey) {
var privateKey = #"-----BEGIN RSA PRIVATE KEY-----
...shortened...
-----END RSA PRIVATE KEY-----";
var bytesToDecrypt = Convert.FromBase64String(encryptedKey);
var decryptEngine = new Pkcs1Encoding(new RsaEngine());
using (var txtreader = new StringReader(privateKey)) {
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)new PemReader(txtreader).ReadObject();
decryptEngine.Init(false, keyPair.Private);
}
var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
return decrypted;
}
But the ProcessBlock method always throws an InvalidCipherTextException "unknown block type".
Can someone help me to find out what am I doing wrong or point me to another better way of achieving this?
Decryption with the C# code fails because in the NodeJS code OAEP/SHA256 is used as padding and in the C# code PKCS#1 v1.5 padding. For decryption to work, both paddings must be identical. The padding in the C# code can be adapted to that of the NodeJS code as follows:
var decryptEngine = new OaepEncoding(new RsaEngine(), new Sha256Digest());
Also, the decrypted key must not be UTF-8 decoded as this corrupts the data. Either it is returned as byte[], or if conversion to a string is desired, a suitable binary-to-text encoding such as Base64 or hex must be used.
With these changes decryption works in the C# code.

Encryption and Decryption in Java and Javascript (Nodejs)

I encrypt a text in Java and want to decrypt in Javascript and vice versa, my Java code looks like this
Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec k = new SecretKeySpec(this.key.getBytes(), "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal(this.value.getBytes());
byte[] iv = c.getIV();
sb.append(new String(Base64.getEncoder().encode(iv)));
sb.append(';');
sb.append(new String(Base64.getEncoder().encode(encryptedData)));
// send sb.toString() to the other end
I tried node-forge and elliptic for decryption in Nodejs, in node-forge I have an error complaining about tag which I don't have, can someone provide a solution in Nodejs.
Javascript Code
function convertFromMxBase64(FormatEncryptedString) {
const speratorIndex = FormatEncryptedString.indexOf(';');
const encryptedBase64 = mxFormatEncryptedString.substr(speratorIndex + 1);
const ivBase64 = mxFormatEncryptedString.substr(0, speratorIndex);
return {
iv: forge.util.createBuffer(forge.util.decode64(ivBase64), 'utf8'),
payload: forge.util.createBuffer(forge.util.decode64(encryptedBase64), 'utf8')
};
}
function decrypt() {
let { iv, payload } = convertFromMxBase64(mxCombi);
const key = forge.util.createBuffer(theKey, 'utf8');
var cipher = forge.cipher.createDecipher("AES-GCM", key); // forge.rc2.createDecryptionCipher(key);
cipher.start({ iv });
cipher.update(payload);
cipher.finish();
var encrypted = cipher.output;
// outputs encrypted hex
console.log(encrypted.toHex());
}
The GCM mode uses by definition a tag which is needed for the authenticity/integrity check.
The tag issue on the NodeJS side is caused by not taking the authentication tag into account. On the Java side this is not necessary because the SunJCE provider does this automatically by appending the tag to the ciphertext: Therefore, the last 16 bytes of the result are the tag. On the NodeJS side, in contrast, ciphertext and tag are handled detached, so that both parts must be explicitly separated, e.g.:
var ciphertext = forge.util.createBuffer(payload.data.substring(0, payload.length() - 16));
var tag = forge.util.createBuffer(payload.data.substring(payload.length() - 16));
Tag and ciphertext must be passed to the cipher instance as follows:
cipher.start({ iv:iv, tag:tag }); // apply tag
cipher.update(ciphertext); // apply ciphertext
Another bug is that the UTF-8 encoding is used when creating iv and payload. This is wrong, the data must be passed as binary string, i.e. 'utf8' must either be replaced by 'binary' or removed completely.
iv: forge.util.createBuffer(forge.util.decode64(ivBase64)),
payload: forge.util.createBuffer(forge.util.decode64(encryptedBase64))
Also, in getBytes() of the Java code an encoding should be specified, e.g. getBytes(StandardCharsets.UTF_8). If this is not done, a platform-dependent default encoding is used, which means that different encodings can be applied depending on the environment.
With these changes, decryption works on the NodeJS side.

Shared ECDH Secret, Browser + NodeJS

I'm trying to use Elliptical Curve Diffie-Hellman keys to create a shared secret between a Browser and NodeJS. If I export the browser public key as raw, everything works, but I'm required to export the key as spki and then NodeJS gets mad about it.
In the Browser I do this:
async function generateDHKeys() {
const key_ECDH = await window.crypto.subtle.generateKey(
{ name: 'ECDH', namedCurve: 'P-256' },
true,
['deriveKey'],
);
const publicKeyData = await window.crypto.subtle.exportKey(
'spki',
key_ECDH.publicKey,
);
const publicKeyBytes = new Uint8Array(publicKeyData);
publicKeyB64 = btoa(String.fromCharCode.apply(null, publicKeyBytes));
const privateKeyData = await window.crypto.subtle.exportKey(
'pkcs8',
key_ECDH.privateKey,
);
const privateKeyBytes = new Uint8Array(privateKeyData);
privateKeyB64 = btoa(String.fromCharCode.apply(null, privateKeyBytes));
privateKeyBytes.fill(0);
return { publicKeyB64, privateKeyB64 };
}
const {publicKeyB64} = await generateDHKeys();
So, now I've exported the Public Key and converted it to Base64. I then send it to the NodeJS server, and I try to create a shared secret:
In NodeJS, I do this:
export function generateDHKeys(foreignPublicKeyB64) {
const ecdh = crypto.createECDH("prime256v1");
ecdh.generateKeys();
const publicKeyB64 = ecdh.getPublicKey("base64");
const privateKeyB64 = ecdh.getPrivateKey("base64");
const sharedSecretB64 = ecdh.computeSecret(foreignPublicKeyB64, "base64", "base64");
const sharedSecretHashB64 = crypto
.createHash("sha256")
.update(sharedSecretB64, "base64")
.digest("base64");
return { publicKeyB64, privateKeyB64, sharedSecretB64, sharedSecretHashB64 };
}
And I get an error saying "Public key is not valid for specified curve."
However, if in the Browser code I export the key as raw (instead of spki) it works....
How can I export the public key as spki in the browser, and then use it to generate a shared secret in NodeJS? Or, how can I convert a Base64 SPKI public key into a raw key in Node?
EDIT
It has been discovered that the Browser Crypto APIs are indeed supported in Node v15.0.0+, meaning my browser JS can be simply copied and run in a Node context. Rather than access window.crypto.subtle as I would in a browser, in a Node application I can import the subtle module like so:
const { subtle } = require("crypto").webcrypto;
HOWEVER... as #Topaco pointed out, as of Node v16.2.0, this API is still experimental and subject to change. See #Topaco's answer for additional information and documentation links.
As far as I know, the NodeJS crypto module does not support the X.509/SPKI format for the public key in ECDH context, but only the raw key. However, it is possible to derive the raw key from the X.509/SPKI key.
The X.509/SPKI key generated with the WebCrypto code encapsulates the raw (more precisely uncompressed) key, 0x04 + <x> + <y>, which is localized at the end. For P-256 aka prime256v1 the last 65 bytes correspond to the raw key. The front part is identical for different P-256 keys.
This way, in the NodeJS code, the raw key for P-256 can be determined as the last 65 bytes from the X.509/SPKI key.
Similarly, the front part of the X.509/SPKI key can be concatenated with the raw key generated with the NodeJS code, thus converting the raw key to the X.509/SPKI format.
The NodeJS code for this is:
// Convert the SPKI key of the WebCrypto side into the raw format
var webcryptoSpkiB64 = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEPF2r2yyMp/PykPZEt6v8WFAvnrf5FsI3UnpEYsbKo7UKVKB8k2hfxxhjKw8p9nulNaRo472hTcEqsSbsGcr5Dg==';
var webcryptoRawB64 = Buffer.from(webcryptoSpkiB64, 'base64').slice(-65).toString('base64'); // the last 65 bytes
// Calculate the shared secret for the NodeJS side
var { publicKeyB64, privateKeyB64, sharedSecretB64, sharedSecretHashB64 } = generateDHKeys(webcryptoRawB64);
// Convert the raw key of the NodeJS side into the SPKI format
var nodejsSpkiB64 = Buffer.concat([
Buffer.from(webcryptoSpkiB64, 'base64').slice(0, -65), // all bytes except the last 65
Buffer.from(publicKeyB64, 'base64')]
).toString('base64');
console.log("Shared secret:", sharedSecretB64);
console.log("SPKI:", nodejsSpkiB64); // will be sent to the WebCrypto side and used there to calculate the shared secret
where generateDHKeys() is the function posted in the question.
Edit: As noted in the comment from the OP, the WebCrypto API is now part of NodeJS, so X.509/SPKI keys are also supported in the context of ECDH via the WebCrypto API within NodeJS. However, it should be mentioned that the WebCrypto API in the current NodeJS version v16.0.2 has stability 1 level (Experimental). This means that non-backward compatible changes or removals are possible. Also, the current LTS version (v14.17.0) does not include the WebCrypto API.

Javascript. How To Efficiently Store Secp256k1 Private Key for ECIES Scheme

I've been having a really hard time figuring out how to store a Secp256k1 privateKey from multiple libraries (currently on this one for ECIES encryption: https://npm.io/package/#toruslabs/eccrypto).
I have tried encoding and decoding with base64, many implementations of functions that copy array buffer for input encoded string to localStoarge and corresponding output Uint8Array from localStorage, I tried it with IndexedDB, JSON.stringify and parse do not work with binary data, and so many more variations.
When I go through the array buffer elements individually to copy it into a new Uint8Array, I get a similar private key, but with two missing key/field's (parent and offset) which I believe is why every library I have tried so far returns something a long the lines of "bad private key" when I try generating the public key from them.
I am exhausted and I would like some professional insight for my lack of skill in this particular subject. So how can I store (in any way as long as it's client/local) a Secp256k1 private key in a way that if I call it from that persistent client sided data base, they can be used to generate the public keys?
Apparently, the library that uses the private/public key (in this case being #toruslabs/eccrypto) requires a buffer parameter for the keys.
A simple solution would be to make the NodeJS Buffer available in the browser, through browserify. You will only need to include the NodeJS Buffer class to the window object when creating the browserify file, as shown:
const eccrypto = require('./index');
window.eccrypto = eccrypto;
window.Buffer = Buffer;
Then, generate the bundle file using browserify: browserify main.js -o bundle.js
After this, you will be able to use the Buffer class in your browser, which will make loading the private/public key possible. Sample code here:
<script src="bundle.js"></script>
<script>
const eccrypto = window.eccrypto;
const privateKey = eccrypto.generatePrivate();
const publicKey = eccrypto.getPublic(privateKey);
// hex string output of private key
const hexPrivateKey = privateKey.toString('hex')
console.log(hexPrivateKey); // we can do this as privateKey is a Buffer
// load private key again
const newPrivateKey = Buffer.from(hexPrivateKey, 'hex');
const enc = new TextEncoder();
// code referenced from #toruslabs/eccrypto README
// Encrypting the message.
eccrypto.encrypt(publicKey, enc.encode("my testing msg")).then(function (encrypted) {
// Decrypting the message.
eccrypto.decrypt(newPrivateKey, encrypted).then(function (plaintext) {
console.log("Message:", plaintext.toString());
});
});
</script>
This should be sufficient to store the hex string of the private key in the localStorage or any client-side database/storage that you will be using.

RSA encrypt using jsencrypt and decrypt using bouncy castle?

Right I've a small problem. I'm using a Javascript library (jsencrypt) to encrypt a message in a browser. This message is then sent to the backend where it is decrypted using a Java library (bouncycastle). My problem is although I can encrypt and decrypt messages using both libraries they don't seem to want to work together. So when I encrypt my message in a browser and send it to the backend I end up getting garbled gibberish. Does anyone have any idea what's going on here?
JSENCRYPT
var text = "This is another msg!";
var pubkey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwyTZf5gRWJdEevtK7sJSz14lhs1Jw7+aFhGtr4cbDGxdiXH8J+BwuYmBc6QFMhRw7AeYcgkx9zPb3SICzr+oK17RMA6T66dH+GPXp75LFUmfONfk2JdSeO80mMODGctSuefWDvoQ24Cq0Bz+ysrhP7hRqvJso5a0GMNPwt8ErtWfz4HZjSsaaZ7gXga2h5dq1OTcGNfevkDN9CJtFW/0Wwb/F6cnXngVHE41rsN4POUB3IWcX2CrCGxSraa+xsT/P7AJ8HRJ4wcjl9G2K/rlHJ8ZXZKlIuWwEzx0/F0IjE+S93tLpDgt6YJxjWqYqjL2uuJAGmEU323+PWA3jFTC+QIDAQAB";
var encrypt = new JSEncrypt();
encrypt.setPublicKey(pubkey);
var ciphertext = encrypt.encrypt(text);
console.log("ciphertext : " + ciphertext);
var decrypt = new JSEncrypt();
decrypt.setPrivateKey($("#privkey").val());
var plaintext = decrypt.decrypt(ciphertext);
console.log("plaintext : " + plaintext);
BOUNCYCASTLE
String cipherText = "jQ/I+oyyIfG5ARIHZsa6MfxwHciCt+3p6l+bLh4NPinq2s8eDjbO9O8abhVt2xuBQQcPAIaqbiP3Y3vRFYLOD2O+inKWiL1SpSBxvUb0XlWMgLmOqWUL6w6sL2iEla3i5EbdlrkK0uLA7QOUc6/fGVyLVe8VL7Vv4BGlo/cxR2FN74HK4MtLFRNaLKejwD6WbCNQoz4sIMA/Ez8GRSVEMyeYVZoWELShvyIRCqVADboAeuEP5l+oFlzgQfW6HFdpPnX+9TnHrbezdWhXiuJiD1Mq4VTicsya50MNcXJuPDV7NINYZs72UCS8NTYvfVkFc2lO7EUlDvvJ7Ns4wWuuWQ==";
PemReader pemReader = new PemReader(new InputStreamReader(new FileInputStream("priv.pem")));
PemObject pemObject = null;
try
{
pemObject = pemReader.readPemObject();
} finally {
pemReader.close();
}
PrivateKey privateKey = EncryptionUtil.generatePrivateKey(pemObject.getContent());
byte[] plainText = EncryptionUtil.asymDecrypt(privateKey, cipherText.getBytes());
System.out.println(new String(plainText));
#EbbeM.Pedersen
You are properly getting different default padding modes. Keywords
like RSA-OAEP padding & PKCS#1 padding comes to mind.
This was indeed the issue. I changed the default padding in bouncycastle to PKCS#1 and it all works now.
Thanks a million.

Categories