1

我需要在 IndexedDB 数据库中存储一个 ECDH P-384 密钥对。这是生成密钥对的代码:

async function generateKeys() {
    // generate client's ECDH asymmetric keypair (privateKey, publicKey)
    return await window.crypto.subtle.generateKey(
        {
            name: "ECDH",
            namedCurve: "P-384",
        },
        true,
        ["deriveKey", "deriveBits"]
    );
}

这是打开数据库的代码,如果它不存在则创建“非对称”对象存储,然后生成并存储密钥对:


var request = window.indexedDB.open("main", 3);
request.onerror = function (event) {
    console.error("Database error: " + event.target.errorCode);
};
request.onupgradeneeded = function (event) {
    db = event.target.result;
    if (!db.objectStoreNames.contains('asymmetric')) {
        console.log('creating OS');
        var objectStore = db.createObjectStore("asymmetric", { keyPath: "owner" });
        objectStore.transaction.oncomplete = function (event) {
            intialKeySetup = true;
        };
    }

};
request.onsuccess = function (event) {
    db = event.target.result;
    if (intialKeySetup) { // first time running
        setupNewKeys();
    } else {
        console.log('loading keys...');
        loadKeys();
    }
};

function setupNewKeys() {
    // Generates ECDH keypair, then saves them to the 'asymmetric' object store with key '#this#'
    return generateKeys().then((kp) => {
        clientKeys = kp;
        var asymOS = db.transaction("asymmetric", "readwrite").objectStore("asymmetric");

        // Error occurs here:
        asymOS.add({ owner: '#this#', keys: kp }); // kp = { publicKey: CryptoKey object, privateKey: CryptoKey object }
        console.log('Done. Wrote keys to DB: ');
        console.log(kp);
        startComm();
    });
}


function loadKeys() {
    // Loads the client's keypair into memory from the 'asymmetric' object store at key '#this#'
    console.log('Attempting to access client keys...');
    var transaction = db.transaction(["asymmetric"]);
    var objectStore = transaction.objectStore("asymmetric");
    var request = objectStore.get("#this#");
    request.onerror = function (event) {
        console.error(event.target.errorCode);
    };
    request.onsuccess = function (event) {
        if (!request.result) {
            setupNewKeys();
        } else {
            console.log(request.result);
            clientKeys = request.result.keys;
            console.log('Retrieved Keys');
            console.log('Starting Comm...');
            startComm(); // connect to WebSocket server
        }
    };
}

此代码在 Chrome、Chromium Edge、macOS Safari、iOS Safari 和 Android 上的 Chrome 上运行良好,但在 Firefox 上不起作用。它不允许它将两个 CryptoKey 对象存储在对象存储中,并生成错误:
Uncaught (in promise) DOMException: The object could not be cloned.
当我尝试存储字符串而不是 CryptoKey 对象时,错误消失了,我可以看到存储在“存储" 开发者工具的标签。为什么不让我将 CryptoKey 存储在 Firefox 的对象存储中?除了导出密钥之外,还有其他解决方法吗?

4

0 回答 0