0

JavaScript の私のスキルは最小限であり、元の Uint8Array(32) が localStorage に送信され、デコードされ、Uint8Array(32) に変換された後に取得する方法がわかりません。以下では、後で使用するために localStorage に送信されるように、秘密鍵を文字列化してから base64 エンコードしようとしたことがわかります。

window.genSKey = function()
{
var secretKey = eccrypto.generatePrivate();
console.log(secretKey);
var skey = JSON.stringify(secretKey);
var SKey = window.btoa(skey);
localStorage.setItem("skey", SKey);
console.log(SKey);
alert(`your private key is ${SKey}`);
return;
}

ここで、localStorage から base64 でエンコードされた文字列を取得し、そこから新しい Uint8Array を作成することで、対応する公開鍵を生成できるように、秘密鍵を取得しようとしていることがわかります。

window.base642Array = function(base64) {
    var binStr = window.atob(base64);
    console.log("binStr"+ binStr);
    var l = binStr.length;
    var bytes = new Uint8Array(l);
    for (var i = 0; i < l; i++) {
        bytes[i] = binStr.charCodeAt(i);
    }
    return bytes.buffer;
}
window.genPKey = function()
{
    console.log("getSKey flag: 0");

    var SKey = getSKey();

    console.log("getSKey flag: 1");

    var publicKey;
    if(SKey != null || undefined)
    {
        console.log(SKey);

        console.log("getSKey flag: 2");

        publicKey = eccrypto.getPublic(SKey);

        console.log("getSKey flag: 3");

        localStorage.setItem("pkey", window.btoa(JSON.stringify(publicKey)));

        return;

    }

    console.log("getSKey flag: alt");

    genSKey();
    genPKey();

    return;
window.getSKey = function()
{
    console.log("getSKey flag: 0");

    var SKey = localStorage.getItem("skey");

    var skey = base642Array(SKey);

    console.log("getSKey flag: 1");

    console.log("getSKey flag: 2");

    console.log(skey);

    return skey;
}

ここで、入力される結果が出力される結果と異なることがわかります。

Uint8Array(32) [247, 145, 236, 54, 52, 10, 202, 187, 35, 79, 42, 141, 230, 76, 228, 2, 109, 228, 72, 92, 221, 139, 235, 147, 244, 10, 149, 220, 196, 175, 11, 128]
0: 247
1: 145
2: 236
3: 54
4: 52
5: 10
6: 202
7: 187
8: 35
9: 79
10: 42
11: 141
12: 230
13: 76
14: 228
15: 2
16: 109
17: 228
18: 72
19: 92
20: 221
21: 139
22: 235
23: 147
24: 244
25: 10
26: 149
27: 220
28: 196
29: 175
30: 11
31: 128
offset: (...)
parent: (...)
buffer: (...)
byteLength: (...)
byteOffset: (...)
length: (...)
Symbol(Symbol.toStringTag): (...)
__proto__: Uint8Array

アウト

ArrayBuffer(141) {}
[[Int8Array]]: Int8Array(141)
[0 … 99]
[100 … 140]
__proto__: TypedArray
[[Uint8Array]]: Uint8Array(141)
[0 … 99]
[100 … 140]
__proto__: TypedArray
byteLength: (...)
__proto__: ArrayBuffer
byteLength: (...)
constructor: ƒ ArrayBuffer()
slice: ƒ slice()
Symbol(Symbol.toStringTag): "ArrayBuffer"
get byteLength: ƒ byteLength()
__proto__: Object
[[IsDetached]]: false

問題は JSON.stringify を使用してネストされた Uint8Array を文字列に変換することだと思いますが、この機能をうまく機能させる他の方法はわかりません。

オブジェクトの入力がオブジェクトの出力と同じでないのはなぜですか? 私はこれを行う方法を学びたいと思っています.助けは私にとって世界を意味します.

4

1 に答える 1

0

いくつかの問題:

  • を使用JSON.stringifyしますが、逆の操作を使用することはありません。JSON.parse

  • を使用charCodeAtしますが、逆の操作、つまり を使用したことはありませんString.fromCharCodecharCodeAt文字列を作成するために行ったこととは関係がないため、これは削除する必要があります。

  • このような問題をデバッグするときは、手順を削除する必要があります。たとえば、次の手順は問題に関連していないことがわかります。

    • ローカル ストレージからの保存と取得。
    • base64 エンコーディングとの間の変換。
    • 暗号化ライブラリの使用

    問題は、型付き配列を文字列に変換して元に戻すことです。

文字列への変換と型付き配列への変換は、お互いの逆ではありません。

これを修正するには、必要な呼び出しを に変更することをお勧めします。これにより、文字列化JSON.stringifyは配列表記 ( で始まる[) になり、単純なオブジェクト表記 ( で始まる) ではなくなります{。だから変更:

JSON.stringify(secretKey);

に:

JSON.stringify(Array.from(secretKey));

次に、その文字列を型付き配列に戻すには、次を使用しますJSON.parse

new Uint8Array(JSON.parse(str))

関係のない手順を除いた小さなデモを次に示します。

function fromTypedArrayToString(arr) {
    return JSON.stringify([...arr]);
}

function fromStringToTypedArray(str) {
    return new Uint8Array(JSON.parse(str));
}

function compareTypedArrays(arr1, arr2) {
    if (arr1.length !== arr2.length) return false;
    for (let i = 0; i < arr1.length; i++) {
        if (arr1[i] !== arr2[i]) return false;
    }
    return true;
}  

// Demo: make a typed array with all possible values
let arr = new Uint8Array([...Array(256).keys()]);
let str = fromTypedArrayToString(arr);
let arr2 = fromStringToTypedArray(str);
let consistent = compareTypedArrays(arr, arr2);
console.log("Is the result consistent:", consistent);

これをコードに適用して、段階的に追加できるはずです。

  • base64 エンコーディングのメリットはわかりませんが、文字列のサイズは 30% 増加します。これがなくてもできます。
  • ローカルストレージ
  • 暗号化モジュール

次のステップに進む前に、上記のスニペットで行ったように、操作を逆にして、型指定された配列の元の値を返すことができることを確認してください。

于 2021-01-03T09:18:21.553 に答える