有人可以提供一个关于如何使用node.js实现数字签名的基本演练吗?我用谷歌搜索,但还没有得到它。说,我有一个API,我想签署并验证每个http请求和它的响应。这就是我目前的想象,请纠正我错在哪里:
1)我需要为客户端生成足够随机的密钥,用于签署请求;
2)结果签名(通过标题提供)是用字符串的密钥散列加密的,必须包括:
然后,服务器将能够检查消息的真实性。
问题:
1)nonce(某个随机值)和时间戳之间的这个上下文有什么区别(我读过一个建议同时使用两者的帖子)?
2)我是否需要在该字符串中包含eTag标头?
3)还应包括上面未列出的其他内容?
4)我应该在API服务器上保留相同的密钥,如在客户端上,并使用它解密和检查请求,或者应该存储在API服务器上的密钥和存储在服务器上的密钥,该密钥与API通信私钥 - 公钥对?如果它们确实需要是私钥 - 公钥密钥对,那么如何在节点中使用公钥(反之亦然)解密使用私钥加密的内容?
Plz,纠正我的描述中的错误并添加,我错过了什么。谢谢。
Amazon REST Authentication是回答你问题的好例子。 AWS要求“签署请求”使用一组规则对请求数据应用HMAC哈希:规范化,编码或时间戳。签名包含在HTTP请求的Authorization标头中
HMAC是一种对称算法,客户端和服务器共享密钥,用于双方计算哈希值。如果它们匹配,则已向授权方发送请求
在这种情况下,不对称的键也很有意义。例如在客户端创建密钥对并在注册期间发送公钥。服务器不需要签署响应。只需使用TLS通道,客户端就可以信任服务器验证服务器证书(TLS还通过加密提供通道权限)
使用共享密钥,需要考虑如何以安全的方式存储秘密,例如(如您所建议的),使用数据库,或加密秘密而不是使用主密钥的普通密钥
即使使用HSM硬件,所有安全解决方案都存在风险。考虑风险 - 收益。如果将密钥存储在DB中,系统管理员或窃取数据库密码的人可以获得所有密钥。在某些情况下,我已经看到使用存储在机器中的主加密密钥(实际上一些HSM只管理这个主密钥)
下面的代码示例使用crypto
库(现在内置于nodejs)来生成文档的数字签名。
const crypto = require('crypto');
const fs = require('fs');
// See keys/README.md on how to generate this key
const private_key = fs.readFileSync('keys/privateKey.pem', 'utf-8');
// File/Document to be signed
const doc = fs.readFileSync('sample-doc.txt');
// Signing
const signer = crypto.createSign('RSA-SHA256');
signer.write(doc);
signer.end();
// Returns the signature in output_format which can be 'binary', 'hex' or 'base64'
const signature = signer.sign(private_key, 'base64')
console.log('Digital Signature: ', signature);
以下是github:digital-signature-for-document-signing的完整代码示例