本文讨论了数字身份验证的问题,分析了英国政府强制推行数字身份的潜在风险,并介绍了欧盟开放数字钱包的方法。文章重点介绍了如何使用BBS签名和JavaScript集成WASM,以实现政府对身份属性的签名,并允许公民选择性地展示身份信息的特定部分,从而保护隐私。最后提供了一个使用WASM和JavaScript创建BBS+签名的示例。

我听说英国政府正在考虑强制公民拥有数字身份,并在被要求时出示。嗯,这种方法在 2001 年就失败了,当时托尼·布莱尔提出的方案因担心政府机构会监视公民而被放弃。因此,英国政府可能正在为自己设置另一个陷阱,而不是宣传使用政府来源证明身份的巨大好处。不过,欧盟正在采取不同的策略,促使数字钱包的开放性,政府只是其中一个身份提供者 —— 而且是一个高度信任的提供者。为此,公民或组织的公钥将被放置在 EBSI 区块链上,然后可以使用存储在钱包中的私钥来签署消息,这些消息将通过受信任的公钥进行验证。
虽然公民方面的管理和设置稍微困难一些,但企业注册部分相当容易,并且存在公钥注册的受信任流程。一个很好的例子是大学授予学术资格,并且会授予数字证书,该证书由大学签署,并且公钥将放置在 EBSI 账本上,然后由任何其他实体验证。
但是,政府派生身份的问题在于,政府通常会签署一系列身份属性,并且在大多数情况下,我们只需要展示其中一个或多个(例如我们的地址)。为此,我们可以使用 BBS 签名,政府签署身份证明,然后公民可以展示他们想要的已证明身份的部分。
在下文中,我们将使用 BBS 签名和 JavaScript,集成 WASM,然后生成一个总签名(来自政府),并将其颁发给 Peggy。然后,她可以获取其中一个属性,并生成一个可以针对主签名进行测试的证明 [here]:
<style>
    .dropdown {
        font-size: 16px;
        border: 2px solid grey;
        width: 100%;
        border-left: 12px solid green;
        border-radius: 5px;
        padding: 14px;
    }
    pre {
        font-size: 16px;
        border: 2px solid grey;
        width: 100%;
        border-left: 12px solid green;
        border-radius: 5px;
        padding: 14px;
    }
    textarea {
        font-size: 20px;
        border: 2px solid grey;
        width: 100%;
        border-radius: 5px;
        padding: 14px;
    }
</style>
<div class="indented">
    <h2>BBS+</h2>
    <table width="100%">
        <tr>
            <th width="15%" valign="top">生成密钥</th>
            <td style="text-align:left">
                <p>
                    <input id="genkey" class="btn btn-large btn-primary" type="button" value="重新生成密钥" />
                </p>
            </td>
        </tr>
        <tr>
            <th width="15%" valign="top">消息 1</th>
            <td>
                <textarea cols="20" id="message1" name="message1" rows="1" style="width:100%"></textarea>
            </td>
        </tr>
        <tr>
            <th width="15%" valign="top">消息 2</th>
            <td>
                <textarea cols="20" id="message2" name="message2" rows="1" style="width:100%"></textarea>
            </td>
        </tr>
    </table>
    <h2>生成的密钥</h2>
    <table width="100%">
        <tr>
            <th width="15%" valign="top">私钥</th>
            <td>
                <pre id="PrivateKey"></pre>
            </td>
        </tr>
        <tr>
            <th width="15%" valign="top">公钥</th>
            <td>
                <pre id="PublicKey"></pre>
            </td>
        </tr>
        <tr>
            <th width="15%" valign="top">签名</th>
            <td>
                <pre id="Signature"></pre>
            </td>
        </tr>
        <tr>
            <th width="15%" valign="top">已验证</th>
            <td>
                <pre id="Verified"></pre>
            </td>
        </tr>
    </table>
    <h2>第一个消息的证明</h2>
    <table>
        <tr>
            <th width="15%" valign="top">证明</th>
            <td>
                <pre id="proof"></pre>
            </td>
        </tr>
        <tr>
            <th width="15%" valign="top">验证证明</th>
            <td>
                <pre id="proof_verify"></pre>
            </td>
        </tr>
    </table>
</div>
<script type="module">
    function buf2hex(buffer) {
        var u = new Uint8Array(buffer),
            a = new Array(u.length),
            i = u.length;
        while (i--) // map to hex
            a[i] = (u[i] < 16 ? '0' : '') + u[i].toString(16);
        u = null; // free memory
        return a.join('');
    };
    (async function () {
        const docknetworkcryptoWasm = await import("https://cdn.jsdelivr.net/npm/@docknetwork/crypto-wasm@0.33.0/+esm");
        async function update() {
            // Load the WASM module
            await docknetworkcryptoWasm.initializeWasm();
            const message1 = new TextEncoder().encode(document.getElementById("message1").value);
            const message2= new TextEncoder().encode(document.getElementById("message2").value);
            // Generate some random msgs
            const msgs = [\
                new TextEncoder().encode(message1),\
                new TextEncoder().encode(message2)\
            ];
            const label = new TextEncoder().encode("My label");
            const messageCount = msgs.length;
            // The label generates deterministic params
            const sigParams = docknetworkcryptoWasm.bbsPlusGenerateSignatureParamsG1(messageCount, label);
            // Generate key pair
            const sk = docknetworkcryptoWasm.bbsPlusGenerateSigningKey();
            const pk = docknetworkcryptoWasm.bbsPlusGeneratePublicKeyG2(sk, sigParams);
            document.getElementById('PrivateKey').innerText = buf2hex(sk);
            document.getElementById('PublicKey').innerText = buf2hex(pk);
            // Generate the signature
            const sig = docknetworkcryptoWasm.bbsPlusSignG1(msgs, sk, sigParams, true);
            document.getElementById('Signature').innerText = buf2hex(sig);
            // Verify the signature
            const isVerified = docknetworkcryptoWasm.bbsPlusVerifyG1(msgs, sig, pk, sigParams, true);
            document.getElementById('Verified').innerText = JSON.stringify(isVerified);
        // Set the first message to prove
            const revealed = new Set();
            revealed.add(0);
            const revealedMsgs = new Map();
            revealedMsgs.set(0, msgs[0]);
            const proof_of_signature = docknetworkcryptoWasm.bbsPlusInitializeProofOfKnowledgeOfSignature(
                sig,
                sigParams,
                msgs,
                new Map(),
                revealed,
                true
            );
            // Define a challenge from the Prover
            const prover_challenge = docknetworkcryptoWasm.generateChallengeFromBytes(docknetworkcryptoWasm.bbsPlusChallengeContributionFromProtocol(proof_of_signature, revealedMsgs, sigParams, true));
            const proof = docknetworkcryptoWasm.bbsPlusGenProofOfKnowledgeOfSignature(proof_of_signature, prover_challenge);
           document.getElementById('proof').innerText = buf2hex(proof);
            // Verify the proof
            const challengeVerifier = docknetworkcryptoWasm.generateChallengeFromBytes(docknetworkcryptoWasm.bbsPlusChallengeContributionFromProof(proof, revealedMsgs, sigParams, true));
            const proof_verified = docknetworkcryptoWasm.bbsPlusVerifyProofOfKnowledgeOfSignature(
                proof,
                revealedMsgs,
                challengeVerifier,
                pk,
                sigParams,
                true,
            );
            const proof_verifiedString = JSON.stringify(proof_verified);
            document.getElementById('proof_verify').innerText = JSON.stringify(proof_verified);
        }
        document.getElementById("message1").addEventListener("input", update);
        document.getElementById("message2").addEventListener("input", update);
        document.getElementById("message1").innerText = "Hello";
        document.getElementById("message2").innerText = "Hello123";
        document.getElementById("genkey").addEventListener("click", update);
        update();
        message1.focus();
    })();
</script>一个示例运行显示了 Peggy 年龄的证明以及证明的验证:

演示在这里:
使用 WASM 和 JavaScript 为 BBS+ 签名创建证明 \ \ 我们能否为一组会员生成数字签名,从而无法知道谁签署了…\ \ asecuritysite.com
- 原文链接: medium.com/asecuritysite...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
 
                如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!