Reputation: 779
I've been trying to crack this for a while with no success.
The server-side decryption uses RSACryptoServiceProvider RSA-OAEP. I can't change this
public void SetEncryptedPassword(string password) {
using (RSACryptoServiceProvider decrypter = new RSACryptoServiceProvider()) {
decrypter.FromXmlString(Resources.PrivateKey);
var decryptedBytes = decrypter.Decrypt(Convert.FromBase64String(password), true);
_password = Encoding.UTF8.GetString(decryptedBytes).ToSecureString();
}
}
I am trying to implement a web client that can access this service but I can't get the encryption right. I have tried loads of libraries but found the most help with SubtleCrypto, which at least can accept the public key provided by the server. I had to add the kty, alg and ext properties and encode the key as URL Base64, but it appears to import fine. Encryption does come back with something so I guess it's working?
const encrypt = async (msg)=>{
let msgBytes = stringToBytes(msg);
let publicKey2 = await window.crypto.subtle.importKey("jwk",publicKey, {name:"RSA-OAEP", hash:"SHA-256"}, true, ["encrypt"]).catch((issue)=>console.log(issue));
var result = await window.crypto.subtle.encrypt({name: "RSA-OAEP"}, publicKey2, msgBytes );
var toBase64 = _arrayBufferToBase64(result);
return toBase64;
}
I had a few issues getting a valid base64 string so now I'm using this
function _arrayBufferToBase64( 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 window.btoa( binary );
}
The result looks a little shorter than the outputs produced by the iPad and .net services, but I have no idea if that means anything.
The decryption always fails with the error "Error occurred while decoding OAEP padding.", which tells me that it fails at the first step.
Am I doing something wrong? Any advice would be helpful. I'll be watching comments and replies for most of the day so I can supply extra information if you ask for it.
Thanks in advance
Upvotes: 1
Views: 1387
Reputation: 49341
The problem arises because in the C#-code SHA-1 is (implicitly) used for OAEP and in the JavaScript/Node.js-code SHA-256.
RSACryptoServiceProvider
only supports PKCS#1 v1.5-padding and OAEP with SHA-1. The support of OAEP with SHA-2 is only
implemented for the newer RSA implementation, RSACng
(available since .NET 4.6), which belongs to the new Cryptography API (Next Generation).
Since you can't change the C#-code according to your own statement, there is only the possibility to change the hash in the JavaScript/Node.js-code from SHA-256 to SHA-1.
Upvotes: 1