问题

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

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

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;

}

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;

?>

回答1:

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

回答2:

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.

来源:https://stackoverflow.com/questions/29615420/rsa-oaep-sha-512-encrypt-decrypt-from-javascriptwebcrypt-api-to-php-openssl

php+ctypt+api,RSA-OAEP SHA-512 Encrypt / Decrypt from Javascriptwebcrypt api to PHP openssl?相关推荐

  1. Linux C/C++ Openssl RSA Encrypt/Decrypt(加密/解密) 简单示例教程

    PEM文件有以下格式 1.PEM私钥文件格式 -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY----- 生成该密钥的Linux命令 : ...

  2. 阿里云API网关(6)用户指南(开放 API )

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  3. api.php t.cn,PHP通过调用新浪API生成t.cn格式短网址链接的方法详解

    本文实例讲述了PHP通过调用新浪API生成t.cn格式短网址链接的方法.分享给大家供大家参考,具体如下: 新浪提供了长链接转为短链接的API,可以把长链接转为 t.cn/xxx 这种格式的短链接. A ...

  4. 基于百度地图的python开发服务端_python编程之API入门: (一)使用百度地图API查地理坐标...

    在网络编程中,我们会和API打交道.那么,什么是API?如何使用API呢?本文分享了一下我对API的理解以及百度地图API的使用. API是"Application Programming ...

  5. python怎么编程输入坐标_python编程之API入门: (一)使用百度地图API查地理坐标...

    在网络编程中,我们会和API打交道.那么,什么是API?如何使用API呢?本文分享了一下我对API的理解以及百度地图API的使用. API是"Application Programming ...

  6. api网关和esb区别_具有ESB,API管理和Now .. Service Mesh的应用程序网络功能。

    api网关和esb区别 我最近谈论了微服务模式的演变,以及来自Lyft的Envoy之类的服务代理如何帮助将弹性,服务发现,路由,指标收集等责任推到应用程序下一层. 否则,我们冒着希望并祈祷各种应用程序 ...

  7. swagger api文档_带有Swagger的Spring Rest API –创建文档

    swagger api文档 使REST API易于使用的真正关键是好的文档. 但是,即使您的文档做得很好,您也需要设置公司流程的权利以正确,及时地发布它. 确保利益相关者按时收到是一回事,但是您也要负 ...

  8. api中重载函数的原理_小心重载API方法

    api中重载函数的原理 重载方法是API设计中的一个重要概念,尤其是当您的API是流利的API或DSL( 特定于域的语言 )时. 对于jOOQ就是这种情况,在这种情况下,您经常想使用与完全相同的方法名 ...

  9. 参与 API 创新应用大赛,体验RDS费用管理 API

    在使用云产品的过程中,对于企业用户而言,费用管理也是很重要的一环.阿里云的RDS就提供了费用管理的相关API,来帮助我们更好的对RDS使用费用进行管理.此次,在API创新应用大赛中,也有参赛者对RDS ...

  10. Web Api 内部数据思考 和 利用http缓存优化 Api

    在上篇<Web Api 端点设计 与 Oauth>后,接着我们思考Web Api 的内部数据: 其他文章:<API接口安全加强设计方法> 第一  实际使用应该返回怎样的数据 ? ...

最新文章

  1. 声卡硬件测试软件,RMAA声卡检测(RightMark Audio Analyzer)
  2. flask urllib上传图片
  3. 教徒计划出品:AIM-IPS升级到7.0步骤
  4. java中文 x_java环境url中文参数乱码处理
  5. ansible-playbook相关
  6. 51中断编程c语言,[新人求指教]51C语言编程可否用中断令循环结束提早结束
  7. CoreJava 笔记总结-第十二章 并发-2
  8. 漫话:应用程序被拖慢?罪魁祸首竟然是Log4j!
  9. Java并发编程实战————可重入内置锁
  10. IoU-aware的目标检测,显著提高定位精度
  11. 用友2003年度NC_SCM项目经理/高级顾问认证考试试题及答案
  12. 【分立元件】电感器(inductor)——简介
  13. 使用gevent的Pool实现异步并发
  14. 关于华硕电脑进入bios
  15. matlab匿名函数如何写,matlab的匿名函数
  16. Spring项目-在线五子棋
  17. RestAssured接口测试框架
  18. 2020电工(初级)考试题及电工(初级)模拟考试系统
  19. SSIS学习之SSIS介绍
  20. swiper 上滑触发_最火英雄小书包:用最矮的身高,打出最高的输出,死上最多的次数...

热门文章

  1. python写病毒代码_十行 Python 代码写一个USB病毒
  2. 毕业设计-基于stm32的校园旧物回收系统
  3. 宝藏又小众的金属板材质贴图素材网站分享
  4. 仿 微信飞机大战项目
  5. micropython 人脸识别检测_基于ESP8266的人脸识别球锁开锁方案
  6. Tapestry5 grid
  7. Quartz插件的使用
  8. 批量部署windows和linux系统,使用Cobbler批量部署Linux和Windows:Windows系统批量安装(三)...
  9. 《Java开发实战经典》笔记
  10. 基于大数据的软件智能化开发方法与环境