I am trying to encrypt with Java (using javax.crypto.Cipher
) and decrypt with JavaScript (using crypto.subtle
). What I am doing is, I make the JavaScript side generate the key pair, then send the public key to the Java side by the following:
$(window).on("load", function () {
const enc = new TextEncoder();
const dec = new TextDecoder();
crypto.subtle.generateKey({
name: "RSA-OAEP",
modulusLength: 1024,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
).then(function ({ privateKey, publicKey }) {
crypto.subtle.exportKey("spki", publicKey).then(function (spki) {
const strPublicKey = spkiToString(spki);
// SEND THE PUBLIC KEY TO THE SERVER (JAVA)
});
});
});
function spkiToString(keydata) {
var keydataS = arrayBufferToString(keydata);
return window.btoa(keydataS);
}
function arrayBufferToString(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return binary;
}
The server uses the public key for encryption:
try {
String publicKey = ""// this will come from the JS side
String message = "encrypt me"//
byte[] publicBytes = Base64.getDecoder().decode(publicKey).getBytes());
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"),
PSource.PSpecified.DEFAULT);
cipher.init(Cipher.ENCRYPT_MODE, pubKey, oaepParams);
return Base64.getEncoder().encode(cipher.doFinal(message));
} catch (Exception e) {
e.printStacktrace();
}
return new byte[0];
The resulted value is then returned to the Javascript side, so it can decrypt the message:
const encryptedToken = "" // this will be obtained from the server
crypto.subtle.decrypt({
name: "RSA-OAEP",
hash: { name: "SHA-256" }
},
privateKey,
enc.encode(atob(encryptedToken))
).then(function (result) {
console.log("decrypted", dec.decode(result))
}).catch(function (e) {
console.log(e);
})
When the Javascript tries to decrypt, it throws a DOMException
with no message (check the attached image).
What I am doing wrong? Thank you in advanced.