我的安全devise听起来如何?

我有一个特定的安全需求,这意味着我正在编写更多与安全相关的代码。 如果我正在做的事情是由某个图书馆解决的,请告诉我,我立即放弃执行。

我有一个用Java编写的服务器(实际上是Clojure)和一个用JavaScript编写的客户端(实际上是ClojureScript),它作为一个Electron应用程序来运行。 我需要各种客户端应用程序来通过服务器交换信息,以便能够访问这些信息:我需要端到端的encryption

为了实现端到端encryption,我希望在客户端生成一个私有的公钥对,然后公钥和私钥的encryption版本将被上传到服务器。 然后,通过做一个挑战响应,在这个响应中,客户端签署一段随机数据,服务器validation它,服务器将authentication用户。

注册过程包括生成一个椭圆曲线Diffie Hellman密钥对,具体来说,根据https://security.stackexchange.com/questions/78621/which-elliptic-curve-应该-I-使用

生成后,生成一个16字节的盐,然后我pbkdf2密码872791次与盐,keylen 32和使用sha512。 使用哈希密钥,我用aes-256-ctrencryption私钥。 最后一步是连接salt长度,salt和encryption的私钥并发送给服务器。

我假定所有这一切都发生在TLS安全通道HTTPS上,通过CA以通常的方式validation服务器证书的有效性。 将来我可能会使用证书locking来增加安全性。

这是一个健全的devise? 它看起来安全吗? 是否有任何或所有这些我可以委托给维护良好的第三方开源库?

我的实际代码:

(def elliptic-curve-name "secp521r1") ; https://security.stackexchange.com/questions/78621/which-elliptic-curve-should-i-use (def encryption-algorithm "aes-256-ctr") ; http://lollyrock.com/articles/nodejs-encryption/ (def hash-bytes 32) (def salt-bytes 16) (def pbkdf-digest "sha512") (def iterations 872791) (defn encrypt-text [text key] (let [salt (.randomBytes crypto salt-bytes) salt-string (.toString salt "base64") hashed-password (.pbkdf2Sync crypto key salt iterations hash-bytes pbkdf-digest) text-cipher (.createCipher crypto encryption-algorithm hashed-password) encrypted-text (gstring/format "%04d%s%s%s" (count salt-string) salt-string (.update text-cipher text "utf8" "hex") (.final text-cipher "hex"))] encrypted-text)) (defn decrypt-text [encrypted-text key] (let [salt-length (js/parseInt (subs encrypted-text 0 4) 10) salt (.from js/Buffer (subs encrypted-text 4 (+ salt-length 4)) "base64") hashed-key (.pbkdf2Sync crypto key salt iterations hash-bytes pbkdf-digest) encrypted-text (subs encrypted-text (+ salt-length 4)) text-decipher (.createDecipher crypto encryption-algorithm hashed-key)] (str (.update text-decipher encrypted-text "hex" "utf8") (.final text-decipher "utf8")))) (defn generate-key-pair [password] (let [diff-hell (.createECDH crypto elliptic-curve-name) public-key (.generateKeys diff-hell "base64") private-key (.getPrivateKey diff-hell "base64") encrypted-private-key (encrypt-text private-key password)] [public-key private-key encrypted-private-key])) 

       

网上收集的解决方案 "我的安全devise听起来如何?"

这是一个很好的开始。 这些问题很棘手,没有办法certificate这些事情是安全的。 有一些很好的概念性的“支柱”来指导它们:

安全的支柱:

  • 隐私:此代码不提供。 中间的攻击者可以读取消息的结构,几乎可以理解所有消息。 这给了他们强烈的立场。 这个系统是开放的重播攻击。

  • 身份validation通过匹配密码哈希值,可以确保此人确实知道密码。 带盐的PBKDF2是最先进的,看起来像你有这个下降。

  • 完整性:此代码不提供。 公钥可以在飞行中更改。 攻击者可以用自己的公钥替代,并导致系统生成消息,然后读取。 这种攻击依赖于系统的其他部分,通过比较公钥和私钥来检测违规行为并做出回应。 这可以通过允许通常被认为是危险的“select的关键攻击”来将系统打开到已知或未知的encryption攻击。 您确实需要确保整个消息的完整性。 攻击者可以将他们知道的密码和密钥与他们知道的私钥一起取出并切换。 结合重播攻击,这可能会破坏系统。

build议:

  • 整个消息的结构必须经过authentication。 有两种方法。 要么使用密钥的MAC(消息authentication码),要么使用“Authenticated Encryption”algorithm。 MAC被包含在更多常见的encryption库中。 不要推出自己的MAC,也不要尝试使用散列。
  • 信息的隐私应该得到保证。 这可以通过确保消息通过TLS发送来完成(您可能已经在执行此操作)。
  • 该消息必须包括防止重播攻击。 这可以通过许多方式来完成。 一个强有力的方法是使用NONCE(Number used ONCe),所以服务器将只接受每个消息一次。 这不能是“每个用户”,因为许多重播攻击是交叉用户。

你绝对正确地做的部分是在这个过程的早期要求公众进行审查。 这使您超越了行业规范。 记住这一点

“任何人,从最无知的业余人员到最好的密码学家,都可以创build一个他自己无法破解的algorithm。”

https://www.schneier.com/blog/archives/2011/04/schneiers_law.html

编辑:确保密码,保护他们免受你猜测他们的私钥是不是你使用相同的密码进行身份validation(并没有办法让他们使用相同的密码)