【问题标题】:Web Crypto API crypto.subtle is undefined in Apache CordovaWeb Crypto API crypto.subtle 在 Apache Cordova 中未定义
【发布时间】:2019-07-26 14:39:26
【问题描述】:

我正在使用 Cordova 和 forge library 以及浏览器的 Web Crypto API 来执行 signimportKey 操作。尽管如此,Android 设备上的 Web Crypto API 仅提供 crypto.getRandomValues() 并且 SubtleCrypto 未定义(crypto.subtle)。所以我想添加Web Crypto API shrim 和它的依赖Promiz 会修复这个引用丢失,但没有任何改变。请问有什么办法吗?

在 Chrome 52.0.2743.116 中的 PC 上调试提供了完整的 Web Crypto API,但在具有 Android 4.4.4 的 Chrome 版本 52.0.2743.98 的 Android 设备上。 Web API 仅限于 crypto.getRandomValues()。

我基本上是在重写How to load a PKCS#12 Digital Certificate with Javascript WebCrypto API的答案

代码示例:

index.html 内

<script src="lib/promiz.min.js"></script>
<script src="lib/webcrypto-shim.js"></script>

在 javascript 文件中

//working with forge without issue
var pkcs12Der = forge.util.decode64(pk);
var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);
var pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, "password");
console.log(pkcs12);

privateKey = null;
// load keypair and cert chain from safe content(s) 
for (var sci = 0; sci < pkcs12.safeContents.length; ++sci) {
    var safeContents = pkcs12.safeContents[sci];

    for (var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) {
        var safeBag = safeContents.safeBags[sbi];

        // this bag has a private key
        if (safeBag.type === forge.pki.oids.keyBag) {
            //Found plain private key
            privateKey = safeBag.key;
        } else if (safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) {
            // found encrypted private key
            privateKey = safeBag.key;
        } else if (safeBag.type === forge.pki.oids.certBag) {
            // this bag has a certificate...        
        }
    }
}

//function for importingKey 
function _importCryptoKeyPkcs8(privateKey, extractable) {
    var privateKeyInfoDerBuff = _privateKeyToPkcs8(privateKey);

    //import key will not work due to missing reference crypto.subtle
    return window.crypto.subtle.importKey(
        'pkcs8',
        privateKeyInfoDerBuff, {
            name: "RSASSA-PKCS1-v1_5",
            hash: {
                name: "SHA-256"
            }
        },
        extractable, ["sign"]);

}

_importCryptoKeyPkcs8(privateKey, true).
then(function(cryptoKey) {
   //sign will not work due to missing reference crypto.subtle
    window.crypto.subtle.sign({
                name: "RSASSA-PKCS1-v1_5"
            },
            cryptoKey,
            digestToSignBuf)
        .then(function(signature2) {

        });
});

【问题讨论】:

  • 你能给我们看示例代码吗?特别是使用 webcrypto-shim 库。
  • @e666 添加了代码示例。它无法正确引用未定义的 window.crypto.subtle。
  • Forge 不能完全做到这一点吗?你确定你需要window.crypto吗?
  • 我认为Android WebView没有WebCryptographyApi,但是为什么需要WebCrypto或者forge呢? Android 原生支持 pkcs12 文件、签名和验证。甚至它从版本 18 developer.android.com/training/articles/keystore.html 开始具有本机密钥存储。我知道缺点是您需要一个本机组件才能从 Cordova 连接。或者,我认为你可以只使用锻造,正如@ArtjomB 所建议的那样。
  • 浏览器中 WebCrypto API 背后的一个想法是让您在浏览器中使用 Javascript 进行安全的加密计算。通过使用 shims 和 pollyfills,您可以让您的应用正常运行,但安全性较低。

标签: android cordova cryptography webcrypto-api


【解决方案1】:

SubtleCrypto 应该在不安全的上下文中未定义。我猜你使用的是http协议。切换到 https 来解决问题。我曾经因此浪费了 4 个小时的开发时间。

编辑:如果 SubtleCrypto 未定义并且您在其上调用了某个函数,您会期望会有一条错误消息,但不会有任何错误、警告或任何东西。没有。这就像调用一个空函数。调试时真的很痛苦。

【讨论】:

    【解决方案2】:

    我在 Cordova 应用程序中的 Web Crypto API 也有很多问题,没有找到导入或保存密钥的解决方案。

    但是我昨天发现的是这个 JS-Library:

    https://github.com/wwwtyro/cryptico

    也许您可以更改代码并使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-14
      • 2017-07-17
      • 2016-08-14
      • 2022-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多