简体   繁体   中英

RSA-OAEP SHA-512 Encrypt / Decrypt from Javascriptwebcrypt api to PHP openssl?

I've been rather busy trying to get a secure exchange established between a browserclient, using the webcrypto api and PHP server using openssl. I've broken down things as much as I can. I wrote some javascript to generate a keypair, print out the values private and public, encrypt a simple string and print it out as well.

I've copied the values straight to a simple php script. Trying to decode it with the values from the javascipt.

Encoding and decoding works properly in the javascript (as posted below), decoding in php does not (also posted beneath the javascript). I also can't seem to find where to set the SHA-512 declaration in PHP. Does anyone have experience with this kind of exchange and perhaps point me in the right direction. RSA-OAEP was chosen because it's supported by chrome, mozilla, IE11 and Safari as well as PHP.

Kind regards, Gideon

 // JavaScript Document var keyPair; var pemPublicKey; var pemPrivateKey; var _spki; var _pkcs8; window.crypto.subtle.generateKey({ name: "RSA-OAEP", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), // 24 bit representation of 65537 hash: {name: "SHA-512"} }, true, ["encrypt", "decrypt"]) .then(function(newKeyPair) { keyPair = newKeyPair; return keyPair; }) .then(function(keyPair) { window.crypto.subtle.exportKey('spki', keyPair.publicKey) .then(function(spki) { _spki = spki; var pemPublicKey = convertBinaryToPem(spki, "PUBLIC KEY"); document.writeln(pemPublicKey); sendToPhp(); }); window.crypto.subtle.exportKey('pkcs8', keyPair.privateKey) .then(function(pkcs8) { _pkcs8 = pkcs8; var pemPrivateKey = convertBinaryToPem(pkcs8, "PRIVATE KEY"); document.writeln(pemPrivateKey); }) }); function sendToPhp() { window.crypto.subtle.importKey('spki', _spki, {name:"RSA-OAEP", hash: {name: "SHA-512"}}, false, ["encrypt"]) .then(function(cryptokey) { window.crypto.subtle.encrypt({ name: "RSA-OAEP"}, cryptokey, str2ab('mijn geheimpje') ) .then(function(encrypted){ //returns an ArrayBuffer containing the encrypted data document.writeln(arrayBufferToBase64String(encrypted)); receivedFromPhp(arrayBufferToBase64String(encrypted)); }); }); } function receivedFromPhp(encrypted) { window.crypto.subtle.importKey('pkcs8', _pkcs8, {name:"RSA-OAEP", hash: {name: "SHA-512"}}, false, ["decrypt"]) .then(function(cryptokey) { window.crypto.subtle.decrypt({ name: "RSA-OAEP"}, cryptokey, base64StringToArrayBuffer(encrypted) ) .then(function(decrypted){ //returns an ArrayBuffer containing the encrypted data var decryp = ab2str(decrypted); debugger; }); }); } function ab2str(buf) { return String.fromCharCode.apply(null, new Uint16Array(buf)); } function str2ab(str) { var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char var bufView = new Uint16Array(buf); for (var i=0, strLen=str.length; i<strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } function base64StringToArrayBuffer(base64) { var binary_string = 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 arrayBufferToBase64String(arrayBuffer) { var byteArray = new Uint8Array(arrayBuffer) var byteString = ''; for (var i=0; i<byteArray.byteLength; i++) { byteString += String.fromCharCode(byteArray[i]); } return btoa(byteString); } function convertBinaryToPem(binaryData, label) { var base64Cert = arrayBufferToBase64String(binaryData); var pemCert = "-----BEGIN " + label + "-----\\r\\n"; var nextIndex = 0; var lineLength; while (nextIndex < base64Cert.length) { if (nextIndex + 64 <= base64Cert.length) { pemCert += base64Cert.substr(nextIndex, 64) + "\\r\\n"; } else { pemCert += base64Cert.substr(nextIndex) + "\\r\\n"; } nextIndex += 64; } pemCert += "-----END " + label + "-----\\r\\n"; return pemCert; } 

 <?php error_reporting(E_ALL); ini_set("display_errors", 1); $pemPublicKey = '-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvzJ07T/SiZsUPfC4ymwj G/TqVdO04QZRUMcsmHeUG0BawSxlwoz+0YD48UZFYyTetw3egoasQfkvOPIUKuqq mPEXwGsVlLbkqvPsgNA2K6Zye8El9DEp83eoPqylopU0L9zSnQp9VaNpSgsOlltr 0RRyq3q8gBJb7PkzuDzmXrr5KEuGmkLmOE3TH0Ck9u+c4xE87g3s5HtQ6uGa6jB6 JooTN1edPum+kBJdJajOW5FvOfDnEHQBsKZPd4HiYcOlM7crt2Y9XnBSBIIZ1uR6 a4Qs+EP6CwczPA6/J5a+GOV9ch1xZLsW5JuO55lCDpwrvKr7VVqwQG3qNewk8vVA iwIDAQAB -----END PUBLIC KEY-----'; $pemPrivateKey = '-----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC/MnTtP9KJmxQ9 8LjKbCMb9OpV07ThBlFQxyyYd5QbQFrBLGXCjP7RgPjxRkVjJN63Dd6ChqxB+S84 8hQq6qqY8RfAaxWUtuSq8+yA0DYrpnJ7wSX0MSnzd6g+rKWilTQv3NKdCn1Vo2lK Cw6WW2vRFHKreryAElvs+TO4POZeuvkoS4aaQuY4TdMfQKT275zjETzuDezke1Dq 4ZrqMHomihM3V50+6b6QEl0lqM5bkW858OcQdAGwpk93geJhw6Uztyu3Zj1ecFIE ghnW5HprhCz4Q/oLBzM8Dr8nlr4Y5X1yHXFkuxbkm47nmUIOnCu8qvtVWrBAbeo1 7CTy9UCLAgMBAAECggEBAK1i7HZacmsnn2usaWfoOM6ZhAjhPB70w7klZmO9zSoJ akPUJ1QO2ObUtuzWdQY74VzPzwE/b+dEOnbB0Vg6Bws7V/a/JYr/cM829Tq7luRu xVNFDU4tZ4XK9WAg4PRXqkPdVYHkiVSoJEtpS4k+zr+Ec5jebSMXgxWbyDNDxwYP p6TenCVIhLGK3cR2uWADsXLAQQ5p5QMnpXDhr2m8cbe7496B4lTwe/gyjomzNutD ZnIQCfAY9r1r7U7ryT2eoNXmb9uDG+fqSaAvaB/kujOT6y1takSxf7Ij26dUL9iA 7h59c2Ztu4PMrISV+04DGYfFs1MzYeBfoz7pxqHEHMECgYEA4IVY54trkJ5/8CId ad1s+bV3exNTJNgTAiqZE/a4eNnBzQD85SGbUAnk9PGzGvW9o3spQkcnJIqqDWJQ cOJlh8HQJqm/0pkWJKonoHUy05SleB67sZz97gAFj/NsPOSSQ6yMnf/pEeKwbrIa /fkOhdjAXk//WnECvo11o6MC7cUCgYEA2gEHoyRS5dbv+FtL1WFn0lNTlMl8tHz3 fAdXuPi5dp3gPhqfxcP5n3QpT9Jc3rhQQaRswbKCjo2YAOhSdHR6nqYTyte+F+H2 ImsqTGFlunIMpXmYK4ssOl00gnG+9cLHDNbHtjCb+oZy9sh8pZZniafSg0aYImo0 VG4RGesbKg8CgYEAq1179vaV+gLP+ZPASX4k4A7ejAS68CMvlva2ceNc93iVEAiR /b0B0zxKEZ6tKoWn4bBuVFUEjkJ7+s0wQoi6H70RR4FGlNIdcYyhxDnPumf5R86F SdJeihpgJHgSBAQdkyOPDEU4OluAeGzeZzyCFizS3ulGKFybUJ+dy3DvGlUCgYBp KjwD8F7pL2G9/lS7z+xkovvb98Ln0q0UsPoZaisV1J07eF6A6cQ+rqvLLODOND3L HMW2PyYKHLYqIei88v/ADr/Xh3HVVZUGD4ptJEMNyTzeiqTkxJOGaDYPg02qgtbB E89tzU9BcKB++kJfIwo5drLvzxtO5srtu9cWGLuW8wKBgQCK0k/hYZyvB+9vELyH fNaVxj+jn5BWOmFtk6/TC/J5dQzldt7uyxkwoWOsJinpc0JByG9TKftaTEZI35xb tcNv214uLovTSNoxk2Yd++Ltg1O2vvjD39NXPIZH8et/unz9PEQXSJjO09Pi9AiH 8a+VdAUhcHLNwqea8T6y5N9N9w== -----END PRIVATE KEY-----'; $encrMessage = 'd14QunL/M8XwYvsogvjkExe24LP1aYY51OM3ACyl3xJam5DnhwBB4o+cf6/tRaBp+AzoZYQuemd7IP3NjYYEHj23DPaxDzoPNfHoWxNfKC9xqcgoLDywEjJvwtvNaJDAO+mGfNHfsi4TFtsSFRvJ8rkxNOYhoprD2XMIEeklSpFHC3V9hnadHunP+Vgwc5TNRCRPZ1AEcEiSlNmBkvd8pB+iMyAwA7P2tmamrpNQYbEjoQu0mCNPUVrft1QI1IS4XWAL4+HP2vBWV41AttL8XjFxicrR3mXXZVukwiu7PJFPjwW9cLGEgTMkcpBkPZoTGPefiCQYVh4LEq6fYb4kdw=='; //just for testing if it works with the public/private keys supplied by javascript, which it does //$publicKey = openssl_pkey_get_public($pemPublicKey); //openssl_public_encrypt('mijn geheimpje',$encr,$publicKey,OPENSSL_PKCS1_OAEP_PADDING); //$encr64 = base64_encode($encr); $privateKey = openssl_get_privatekey($pemPrivateKey); if (!$privateKey) { echo "Cannot get private key"; } $encr = base64_decode($encrMessage); $b = openssl_private_decrypt($encr,$decr,$privateKey,OPENSSL_PKCS1_OAEP_PADDING); if (!$b) { echo "Cannot decode message"; } echo "String decrypt :". $decr; ?> 

Guess I solved my own problem. I played around with phpseclib and got a hint about the hash being wrong. After replacing SHA-512 with SHA-1 it finally worked. In the PHP documentation its says that the crypt libe defaults to SHA-1. Things should have worked properly with phpseclib, being completely independent of the open_ssl php lib. But it didn't. Still at a loss why this happend. But at least I have a working solution to work from... Hope this helps other people working on the same thing.

Gideon

Gideon,

Glad you found your answer. Your issue was not with PHP but with Safari, it does not support OAEP with anything other than SHA1, at least at this time.

If you are going to work with WebCrypto you may want to look at: https://peculiarventures.github.io/pv-webcrypto-tests/ which enumerates the combinations supported by each browser.

We did this as a test suite to help us build https://github.com/PeculiarVentures/webcrypto-liner which makes it easier to build interoperable WebCrypto applications.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM