簡體   English   中英

RSA-OAEP SHA-512從Javascriptwebcrypt api加密/解密到PHP openssl?

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

我一直忙於嘗試在瀏覽器客戶端之間建立安全交換,使用webcrypto api和使用openssl的PHP服務器。 我盡可能地分解了​​事情。 我寫了一些javascript來生成一個密鑰對,打印私有和公共的值,加密一個簡單的字符串並打印出來。

我已經將這些值直接復制到一個簡單的PHP腳本中。 嘗試使用javascipt中的值對其進行解碼。

編碼和解碼在javascript中正常工作(如下所示),在php中解碼不會(也在javascript下面發布)。 我似乎也無法找到在PHP中設置SHA-512聲明的位置。 有沒有人有這種交流的經驗,也許我指出了正確的方向。 選擇RSA-OAEP是因為它受到chrome,mozilla,IE11和Safari以及PHP的支持。

親切的問候,基甸

 // 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; ?> 

猜猜我解決了自己的問題。 我玩弄了phpseclib並得到了關於哈希錯誤的暗示。 用SHA-1替換SHA-512后,它終於奏效了。 在PHP文檔中,它表示crypt libe默認為SHA-1。 事情應該與phpseclib一起正常工作,完全獨立於open_ssl php lib。 但事實並非如此。 仍然不知道為什么會發生這種情況。 但至少我有一個可行的工作解決方案......希望這有助於其他人在同一件事上工作。

吉迪恩

基甸,

很高興你找到了答案。 您的問題不在於PHP,而在Safari中,至少在此時它不支持除SHA1以外的任何其他OAEP。

如果您打算使用WebCrypto,您可能需要查看: https ://peculiarventures.github.io/pv-webcrypto-tests/,它列舉了每個瀏覽器支持的組合。

我們將其作為測試套件來幫助我們構建https://github.com/PeculiarVentures/webcrypto-liner ,這樣可以更輕松地構建可互操作的WebCrypto應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM