gpt4 book ai didi

javascript - Python 中的 Web Crypto API JWK 使用

转载 作者:行者123 更新时间:2023-11-28 06:06:51 24 4
gpt4 key购买 nike

我正在开发一个 P2P 基础设施,它将包含来自一组不同应用程序的数据,并通过网络分发。这个 P2P 覆盖层由一组 Python Twisted 服务器组成。

我需要保证每个应用程序的每个用户所存储数据的安全性和隐私性。因此,我使用 Web Crypto API 在 Web 应用程序的客户端生成 RSA key 对。 。 RSA key 对也将存储在 P2P 覆盖层中。因此,我在客户端对私钥进行加密,并派生出用户密码。

此外,我正在使用 jwk to pem用于将 JWK 公钥转换为 PEM key 的模块,以便在 Python 加密库(PyCrypt 或 m2Crypto)中使用。

最后,我必须保证包含这些凭据以及用户数据的消息保持其完整性。因此,在客户端,我使用用户的私钥对该数据进行签名。

我将 ArrayBuffer 类型的数据以及签名发送到服务器,并以 base64 编码。

function signData(private_key, data, callback){

var dataForHash = str2ab(JSON.stringify(sortObject(data)));
computeSHA(dataForHash, "SHA-256", function(hash){


signRSA(private_key, hash, function(data){
callback(data.buffer.b64encode(), dataForHash.b64encode());
});
});
}

function computeSHA(data, mode, callback){
window.crypto.subtle.digest(
{
name: mode,
},
data
)
.then(function(hash){
callback(new Uint8Array(hash).buffer);
})
.catch(function(err){
console.error(err);
});
}

function signRSA(private_key, data, callback){
window.crypto.subtle.sign(
{
name: "RSASSA-PKCS1-v1_5",
},
private_key,
data
)
.then(function(signature){
callback(new Uint8Array(signature));
})
.catch(function(err){
console.error(err);
});
}

ArrayBuffer.prototype.b64encode = function(){
return btoa(String.fromCharCode.apply(null, new Uint8Array(this)));
};

之后,当Python Server收到这个http请求时,它会从base64解码数据和签名。

dataForHash = base64.b64decode(dataReceived['data'])
signature = base64.b64decode(dataReceived['signature'])

为了验证签名,需要公钥。因此:

data = utils.byteify(json.loads(dataForHash.decode("utf-16")))
pub_key = base64.b64decode(data['pub_key']) # Get PEM Public Key

(utils.byteify() 将 unicode 字符串转换为常规字符串)

验证签名:

Authentication.verifySignature(signature, dataForHash, pub_key)

方法定义:

from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA

def verifySignature(signature, data, pub_key):
key = RSA.importKey(pub_key)
h = SHA256.new(data)
verifier = PKCS1_v1_5.new(key)
return verifier.verify(h, signature)

但是签名验证返回False。我也尝试过使用 m2crypto 库,但它返回 0。

最佳答案

我设法找到了问题。

尽管在 Python (PyCrypto) 中,签名函数应接收要签名的数据的哈希值,但使用 Web 加密 API,签名方法会在对接收到的数据进行签名之前对其应用哈希函数。

因此,JS 中的数据被哈希两次,一次在调用 Sign 方法之前,另一次在 Sign 方法中创建签名之前。

function signData(private_key, data, callback){

var dataForHash = str2ab(JSON.stringify(sortObject(data)));

signRSA(private_key, dataForHash, function(data){

callback(data.buffer.b64encode(), dataForHash.b64encode());
});
}

ArrayBuffer.prototype.b64encode = function(){
return btoa(String.fromCharCode.apply(null, new Uint8Array(this)));
};

String.prototype.b64decode = function(){
var binary_string = window.atob(this);
var len = binary_string.length;
var bytes = new Uint8Array(new ArrayBuffer(len));
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes;
};

经过此修改,python 中的验证现在返回 True。

关于javascript - Python 中的 Web Crypto API JWK 使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36772305/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com