署名検証の実装
実装する機能:
メッセージの署名
検証に必要な値
署名されたデータ a
元のメッセージ m
DID -> DIDからuniversal Resolverを使ってdid documentを呼び出す
署名の検証
didからUniversal resolverを使ってdidDocumentの取得
code:signature.js
//DID documentの取得関数
async function getDIDDocument(did) {
try {
const response = await axios.get(${resolverUrl}${did});
return response.data;
}catch (error){
('Error fetching DID Document: ', error);
throw error;
}
}
上記のコードをテストした
code:getDIDDocument.test.js
const { getDIDDocument } = require('../src/services/signatureService')
async function testGetDIDDocument() {
const did = 'did:ethr:goerli:0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC';
try {
const didDocument = await getDIDDocument(did);
console.log("DID Document:", didDocument);
}catch (error) {
console.error("Error:", error);
}
}
testGetDIDDocument();
ちなみに、module.exports = {}に実行したい関数が含まれていないと、テストが出来なかったYudai.icon
もう忘れることはないね
で、実行結果は、
code:result
DID Document: {
'@context': [
],
'did:ethr:goerli:0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC#controller'
],
id: 'did:ethr:goerli:0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC',
verificationMethod: [
{
id: 'did:ethr:goerli:0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC#controller',
type: 'EcdsaSecp256k1RecoveryMethod2020',
controller: 'did:ethr:goerli:0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC',
blockchainAccountId: 'eip155:5:0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC'
}
],
authentication: [
'did:ethr:goerli:0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC#controller'
]
}
正しく取得できたYudai.icon
次は署名をして、検証をしていく
署名の作成
.envファイルからskを呼び出して署名の作成をしようとしていたけどなぜか一生できなかった
=> path指定をしたらできた
Message: This is test messageSignature: 0xb572f49aae24d3c5b9f3bdd6103e73be10bad101293f62a109e8b6d2236caa6d4ddcbb6ef7b9d02ad9c6e306dab933df15563c4c6b5850e6fc825fbddca64b921c
code:signature.js
//署名の検証関数
async function verifySignature(message, signature, did) {
try {
const didDocument = await getDIDDocument(did);
//DID documentからAddressを取得
const ethereumAddress = didDocument.verificationMethod0.blockchainAccountId.split(':')1; console.log('Extracted Ethereum Address from DID Document:', ethereumAddress);
//署名から公開鍵を回復
const recoveredAddress = web3.eth.accounts.recover(message, signature);
console.log('Recovered Address from Signature:', recoveredAddress);
return recoveredAddress === ethereumAddress;
} catch (error) {
console.error('Error verifying signature:', error);
throw error;
}
}
ちなみに、本当はpkを取得が正しい署名検証だけど、addressの取得に変更させてみたYudai.icon
理由はEtherumの署名検証がaddressの一致になっているからそっちにしてみた
ちなみにpkがどこにあるのかが気になりすぎるw
検証をしているんやけどfalseになった
デバックをした実行結果
Extracted Ethereum Address from DID Document: 5Recovered Address from Signature: 0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC Is the signature valid? false
5って出た瞬間笑ったwYudai.icon
code:signature.js
const blockchainAccountId = didDocument.verificationMethod0.blockchainAccountId const splitResult = blockchainAccountId.split(':');
console.log('Split Result:', splitResult);
const ethereumAddress = splitResult2; console.log('Extracted Ethereum Address from DID Document:', ethereumAddress);
それぞれ分解していったら5が表示された理由が分かった
blockchainAccountIdの値は、eip155:5:0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaCになっていて、1を指定していたから5を呼びだしていた
だから2(つまり3)を指定したら正しく実行されたYudai.icon
Extracted Ethereum Address from DID Document: 0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC
Recovered Address from Signature: 0xaB1839aD0a610aDBB60FF50843Ae860f4f25cdaC
Is the signature valid? true
ちゃんと一致したYudai.icon*2
次に行うのはdid documentを誰でも作成できるようにする事Yudai.icon
つまり今実装しているdidとかの部分を変数にする事とJSONをownerAddressの取得をして作成できるところまで出来ればDIDのログインによってPersonal空間の制御が出来るようになる(はず)Yudai.icon
気付き
よくよく考えたらEOA(例)ではライブラリーを使って署名検証ができるんだからDIDにするのはある意味では無駄かもと思った
=> しかし、公開鍵自体を渡しているのではなくアドレスを渡しているからDIDを渡すのと変わらないから、置き換えることに意味はある
公開鍵(EOA) とDIDが紐づいていると言えない可能性があるからYudai.icon
上記のように思っていたけど、実際は署名からaddressを取得が出来るからやっぱり意味がないとも思っている
ただブロックチェーン上に保存されているとは限らないし、そもそもEthereumがそういう仕様なだけであることは大前提
署名をする際に普段はownerAddressを渡すんだけど、didの仕様に適用させようとするとdid:ethr:0x11111を渡して、didDocumentを呼び出して、そこから取る的なことをする