php エディタ Xiaoxin は、Go 言語を使用して ECDSA 署名を生成するときに問題が発生しました。つまり、JS を検証に使用できませんでした。この問題の解決策は、Go コードにいくつかの追加フィールドを追加して、署名の正確性を保証することです。 Go コードにいくつかの変更を加えることで、この問題を解決し、JS が Go によって生成された ECDSA 署名を正しく検証できるようにすることができます。この記事では具体的な解決策と手順を詳しく紹介します。
タイトルにあるように、小さな問題に遭遇しました(私は小さな問題が私を妨げていると仮定していますが、それが何かはわかりません)。
まず、私がやっていることの概要を説明し、それから私が持っているすべてを提供します。
モバイル アプリで SHA-256
を使用してファイルをハッシュし、ECDSA P-256
キーを使用してバックエンドでハッシュに署名しています。そして、これが延々と続きます。ユーザーが望む場合は、ファイルを再度ハッシュし、ハッシュを検索してハッシュ、メタデータ、および署名を取得することで、ファイルの整合性を検証できます。
データが第三者ではなく私のアプリケーションに送信されたことを検証するために (ハッシュはブロックチェーンに残りますが、この問題では重要ではありません)、アプリケーションは公開キーを使用して署名を検証しようとします。 。この作品は良いです。
さて、このオプションを自分の Web サイトにも追加したいのですが、問題があります。 jsrsasign
または webcrypto
API を使用すると、署名が無効になります。
公開鍵:
###脚本###
JSコード
リーリー
アプリ認証コード(Flutter Dart)
リーリー
鍵生成スクリプト (Go)
リーリー
2 つの新しいキー ペア (およびライブラリ) を使用してサンプル データに署名し、キーの内容が間違っているかどうかをテストしましたが、そうではありません
Firefox と Safari を使用して違いがあるかどうかを確認しましたが、何も変わりませんでした
sig.updateString(hashData) Web サイトとアプリ Web サイトのハッシュ、R&S 署名を比較すると、すべてが予想どおりです。
JavaScript コードでの検証は、次の 2 つの理由により Dart コードと互換性がありません。
<ul>
<li>首先,JavaScript代码使用<a href="https://www.php.cn/link/971436431aef6875a9b7997990809a5f" rel="nofollow noreferrer"><code>KJUR.crypto.Signature ()
,它隐式对数据进行哈希处理。由于数据已经被散列,这会导致双重散列。在 Dart 方面,不会发生隐式哈希(因为 ECDSASigner()
)。
为了避免 JavaScript 端的隐式哈希并与 Dart 代码兼容,KJUR.crypto.ECDSA()
可以用来代替 KJUR.crypto.Signature()
。
updateHex()
对十六进制编码的哈希值执行十六进制解码,而在 Dart 代码中,十六进制编码的哈希值是 UTF-8 编码的。以下 JavaScript 代码解决了这两个问题:
(async () => { var spki = `-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEq6iOuQeIhlhywCjo5yoABGODOJRZ c6/L8XzUYEsocCbc/JHiByGjuB3G9cSU2vUi1HUy5LsCtX2wlHSEObGVBw== -----END PUBLIC KEY-----`; var pubkey = KEYUTIL.getKey(spki).getPublicKeyXYHex() var pubkeyHex = '04' + pubkey.x + pubkey.y var msgHashHex = ArrayBuffertohex(new TextEncoder().encode("bb5dbfcb5206282627254ab23397cda842b082696466f2563503f79a5dccf942").buffer) // var msgHashHex = ArrayBuffertohex(new TextEncoder().encode("bb5dbfcb5206282627254ab23397cda8").buffer); // works also since only the first 32 bytes are considered for P-256 var sigHex = "3045022100f28c29042a6d766810e21f2c0a1839f93140989299cae1d37b49a454373659c802203d0967be0696686414fe2efed3a71bc1639d066ee127cfb7c0ad369521459d00" var ec = new KJUR.crypto.ECDSA({'curve': 'secp256r1'}) var verified = ec.verifyHex(msgHashHex, sigHex, pubkeyHex) console.log("Verification:", verified) })();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/10.4.0/jsrsasign-all-min.js"></script>
以上がGo が生成した ECDSA 署名を JS を使用して検証できないの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。