Я разрабатываю инфраструктуру P2P, которая будет иметь данные из набора различных приложений, распространяемых по сети. Это наложение P2P состоит из набора витых серверов Python.Использование веб-Crypto API JWK в Python
Мне нужно гарантировать безопасность и конфиденциальность сохраненных данных для каждого пользователя каждого приложения. Следовательно, я создаю пары ключей RSA на клиентской стороне веб-приложения, используя Web Crypto API. Пара ключей RSA также будет сохранена в наложении P2P. Итак, я шифрую на стороне клиента, закрытые ключи с выводом пароля пользователя.
Кроме того, я использую модуль jwk to pem для преобразования открытого ключа JWK в ключ PEM, который будет использоваться в библиотеке криптографии 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 получает этот 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() преобразует юникод строку в обычных строк)
Проверка подписи: определение
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.