This is an example to demo how you generate the RSA key pair from server side(.NetCore 3.1) and pass the public key to the client(Browser) for encrypting the data that <= 245 bytes.
RSA-2048 can only support to encrypt up to 245 bytes data.
using var rsaProvider = new RSACng();
// spki is used for browser side encryption
var spki = Convert.ToBase64String(rsaProvider.ExportSubjectPublicKeyInfo());
var encodedPrivateKey = Convert.ToBase64String(rsaProvider.ExportPkcs8PrivateKey());
function base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
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);
}
async function importPublicKey(spki) {
const binaryDer = base64ToArrayBuffer(spki);
var cryptoKey = await window.crypto.subtle
.importKey(
"spki",
binaryDer, {
name: 'RSA-OAEP',
modulusLength: 256,
hash: {
name: 'sha-256'
}
},
false,
["encrypt"]
);
return cryptoKey;
}
async function encryptData(message, publicKey) {
let enc = new TextEncoder();
let encodedMessage = enc.encode(message);
var encryptedData = await window.crypto.subtle.encrypt({
name: "RSA-OAEP"
},
publicKey,
encodedMessage
);
var encodedData = arrayBufferToBase64(encryptedData);
return encodedData;
}
const start = async function() {
// this is spki from C# code.
var spki = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyu9pSV8qF/VUG0MP2ekdlftLS5Ad/wwrF0WCKIfIrSYO6T4vblyuGweQbXKscEuvS2Z8wP4TFU3JSPhRaq7RnFWs0c/UBaQrKSeYEH9iXjJlyGT4N9Shz4lAMLHiMTfxG5fDe\u002B/jUbbEEMXAdcE13lVqUtNLNnEVNq3M1nD5a5MlqCDkdphAaVPlCYcwPZ4v2BEa4ITdejMdJKRiT5jdhFYKUYp0ELtTKm1vU6vSAn6sJvkWJGW5vufOT\u002BJPgxI7o\u002BZfIXP6ln7TSB71KjeY4FrFctPCI/L43wla0LAyjlfgSTQNf9E0XxZnaVCcQe741jhDYS27jHvfAoo/SNLk6QIDAQAB";
var key = await importPublicKey(spki);
var encryptedData = await encryptData("hello world", key);
console.log(encryptedData)
}
start();
using var importedRsa = new RSACng();
var span = (ReadOnlySpan<byte>)Convert.FromBase64String("<EncodedExportedPkcs8PrivateKey>");
importedRsa.ImportPkcs8PrivateKey(span, out int _);
var data = Console.ReadLine();
var bytes = Convert.FromBase64String(data);
var decryptedBytes = importedRsa.Decrypt(bytes, RSAEncryptionPadding.OaepSHA256);
var decryptedData = Encoding.UTF8.GetString(decryptedBytes);
Thank you, this gist helped me! Here is a more up to date codes (.NET 6)
https://github.com/duongphuhiep/AsymmetricEncryptionWebDemo