kjur / jsrsasign

The 'jsrsasign' (RSA-Sign JavaScript Library) is an opensource free cryptography library supporting RSA/RSAPSS/ECDSA/DSA signing/validation, ASN.1, PKCS#1/5/8 private/public key, X.509 certificate, CRL, OCSP, CMS SignedData, TimeStamp, CAdES and JSON Web Signature/Token in pure JavaScript.
https://kjur.github.io/jsrsasign
Other
3.27k stars 643 forks source link

Encrypt hexademical or bytes #531

Closed DNAlchemist closed 2 years ago

DNAlchemist commented 2 years ago

I can't find how to encrypt bytes or hexadecimal (produced by CryptoJS) with RSAES-OAEP (SHA-256 ) encryption. But can't decrypt byte array on backend side (backend code is correct) I'm using postman-utils-lib and do something like that:

    const text = "text"
    const cert = `-----BEGIN CERTIFICATE-----
MIICrDCCAZSgAwIBAgIGAX4LCd/nMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNVBAMM
C2F1dGgtc2VydmVyMCAXDTIxMTIzMDExMTE0M1oYDzIxMjExMjA2MTExMTQzWjAW
MRQwEgYDVQQDDAthdXRoLXNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAPbV6lzXnrgN5ZnzRdgBdOji2OonMRDpV2mRF8oetonhY2pLw3keN/LO
YANU6CqqVubkz5CrT9WIx39eqH45Q2HC8QijqJm41tZtrf9xRX1kWmYK/0ha+U2i
NzfOrQL399d5KpfBla63vx0C4Wh1F0CcQ2Id/1pe/ikjKzMDEAsJIJ39QJhlHD5d
QM8bilImvCDPY6GSqvVKcUXVpC3qieO3dG1+fkhSzsEYRcZ3ozcd4iWKRIuN2hcS
569Vpk7TKyJB2JgNhhDZ4V7K1d59G6i1Gofh0ukvpt5QVFtPUxBW2oLZLQrbBarx
PmBMV6PG/oTp5WpELbG7SWNMYPGdQLcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
c6HOsC92SfmTcqGf03oTV+3ebG61iTrI0fub2WjfxPhLYxWFFDPSEP1xxkNPxbPk
2B7ehyo+MZuhf6g/DYdSVjVKIit8aW6rD1Ef/8hikNBvjY2KWIAdu6iMPHeVnFWS
Q95fPs4XD1VADLY9W5uVRk30EOHyvVx+jlSfluwk4PiGxWRnwhTdO39Vmk4ZDgqD
0+DLMhmfHSqZnsVq1CZxvE+djpKvIka3c6QimKWHR3qV4zUTYBTVxZU+F0mIDfoN
qZ47kqVCN1lTphTaKn5NA52s3d9jeCuQsUGkAnigTlEO/mRsLRk9YugZJTIRKz8F
w5NANuNSVyan2uPNOrNhcQ==
-----END CERTIFICATE-----`

    var salt = CryptoJS.enc.Base64.parse("AAAAAAAAAAABAQEBAQEBAQICAgICAgICAwMDAwMDAwM=");
    const aesKey = CryptoJS.PBKDF2(text, salt, { keySize: 256/32, iterations: 10000, hasher: CryptoJS.algo.SHA256 });

    const publicKey = pmlib.rs.KEYUTIL.getKey(cert)
    const encAes = pmlib.rs.KJUR.crypto.Cipher.encrypt(aesKey.toString(CryptoJS.enc.Hex), publicKey, 'RSAOAEP')
    console.log(pmlib.rs.hextob64(encAes))

It's possible?

kjur commented 2 years ago

1st argument of Cipher.encrypt shall be a raw string not a hexadecimal string. Is this resolve your issue?

DNAlchemist commented 2 years ago

From CryptoJS.PBKDF2 I get bytes, not a string I can cast it to hexadecimal, base64, but not to string cause I getting "Malformed Utf Data" (via CryptoJS)

I also tried

const aesRawString = pmlib.rs.hextorstr(aesKeyHex)
const encryptedAes = pmlib.rs.hextob64(pmlib.rs.KJUR.crypto.Cipher.encrypt(aesRawString, publicKey, 'RSAOAEP'))

But still getting decryption error

kjur commented 2 years ago

I've checked Cipher.encrypt/decrypt.

var prv = rs.KEYUTIL.getKey(prvpem);
var pub = rs.KEYUTIL.getKey(pubpem);

var s1 = "\x01\x02\x03\x00\x01\x02\x03\x00";
var e1 = rs.KJUR.crypto.Cipher.encrypt(s1, pub, "RSAOAEP");
console.log("e1", e1);

var s2 = rs.KJUR.crypto.Cipher.decrypt(e1, prv, "RSAOAEP");
console.log("s2", s2);
console.log("s2hex", rs.rstrtohex(s2)); // -> "0102030001020300"
console.log("cmp", s1 === s2); // -> true

Then Cipher.decrypt/encrypt works properly. Sorry but it seems your CryptoJS string handling issue. Thank you.