【问题标题】:How keep in the secret the RSA - private key in browser - implement Proof of Possession with an Asymmetric Key如何保密 RSA - 浏览器中的私钥 - 使用非对称密钥实现拥有证明
【发布时间】:2017-11-08 23:16:47
【问题描述】:

我想用非对称密钥specs 实现Proof of Possession。

我想将 RSA 存储在浏览器中的安全位置 - 我将能够使用私钥和公钥签署请求的一部分,作为 JWT 验证请求的一部分。

我不知道如何将 RSA 导入我的浏览器 - 我在哪里可以安全地在浏览器中存储 RSA 私钥?

【问题讨论】:

    标签: browser rsa jwt


    【解决方案1】:

    查看 WebCrypto API 和 IndexedDB。这里有一些 WebCrypto 示例 - https://github.com/diafygi/webcrypto-examples。

    这将允许您以无法提取的方式导入密钥 - 仅用于签名和验证签名。但是,当使用“清除应用程序数据”(/类似 - 取决于浏览器)标志清除浏览器数据时,这将被清除。

    例如导入一个密钥并将其存储在 IndexedDB 中(此代码尚未经过测试/必须实现 _openDb)-

    window.crypto.subtle.importKey(
        "jwk", //can be "jwk" (public or private), "spki" (public only), or "pkcs8" (private only)
        {   //this is an example jwk key, other key types are Uint8Array objects
            kty: "RSA",
            e: "AQAB",
            n: "vGO3eU16ag9zRkJ4AK8ZUZrjbtp5xWK0LyFMNT8933evJoHeczexMUzSiXaLrEFSyQZortk81zJH3y41MBO_UFDO_X0crAquNrkjZDrf9Scc5-MdxlWU2Jl7Gc4Z18AC9aNibWVmXhgvHYkEoFdLCFG-2Sq-qIyW4KFkjan05IE",
            alg: "PS256",
            ext: true,
        },
        {   //these are the algorithm options
            name: "RSA-PSS",
            hash: {name: "SHA-256"}, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
        },
        false, //whether the key is extractable (i.e. can be used in exportKey)
        ["verify"] //"verify" for public key import, "sign" for private key imports
    ).then(function(key){
        ((_db_handle === null) ?
            _openDb() :
            Promise.resolve()
        ).then(function() {
            let tx = _db_handle.transaction("KeyStore", "readwrite");
            let store = tx.objectStore("KeyStore");
    
            let putKey = store.put({id: "Key 1", key: key});
    
            putKey.onsuccess = function() {
                resolve();
            };
    
            putKey.onerror = function() {
                reject(putKey.error);
            };
        });
    })
    

    然后再读出来-

    let tx = _db_handle.transaction("KeyStore", "readwrite");
    let store = tx.objectStore("KeyStore");
    
    let getKey = store.get("Key 1");
    
    getKey.onsuccess = function() {
        resolve(getKey.result ? getKey.result.key : null);
    };
    
    getKey.onerror = function() {
        reject(getKey.error);
    };
    

    【讨论】:

    • 旧浏览器中的 Web Crypto 支持怎么样?
    • 对于特定于安全的应用程序,我反对支持过时的浏览器。它适用于最新的 Chrome、IE、Opera 和 Firefox afaik。值得检查 Safari。自 2014 年以来,它一直在 chrome 中——按照浏览器标准,它是古老的。
    • 对于旧版浏览器中的 WebCrypto,您可以使用github.com/PeculiarVentures/webcrypto-liner。这在 JS 中实现了算法,因此您的应用程序可以在下层工作但是 JS 加密的安全属性是不一样的,如果可能的话,鼓励用户升级到更现代的浏览器。
    • 最新的 Safari 确实支持 WebCrypto。您可以使用 peculiarventures.github.io/pv-webcrypto-tests 测试各种 WebCrypto 实现所支持的内容
    【解决方案2】:

    也许您可以创建一个扩展来保存密钥。考虑一下,如果您需要在浏览器中存储私钥,则默认情况下您应该只允许存储加密密钥,此外,如果您想要/需要存储更多密钥,则不允许在不同的密钥文件上使用相同的密码。

    还可以考虑使用主密钥和/或 OTP 来解密存储。

    寻找可以提供这些东西的扩展程序可以节省一些工作

    【讨论】:

    • 扩展是什么意思?您如何看待将密钥存储到 cookie 中?您能否提供一些您提到的概念的 URL?
    • 我的意思是浏览器扩展并将私有 KeyFile 存储在 Cookie 中......听起来不是一个好习惯......作为用户,您更喜欢隐藏密钥处理还是可见一 ? cookie 可以被删除、捕获等等......我不认为这是一个好主意...... OTP 是 OneTimePassword tools.ietf.org/html/rfc6238,你可能从 goolge authentifiactor or 2 way loginauthentification 知道它
    • 也许您可以将密钥存储在浏览器密码库中,这也是一个很好的解决方案,并且已经实现
    • 好的,您可以发送有关 MasterKey 概念的规范吗?这也可能是个好点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多