【问题标题】:Obtain public key byte array from Json Web Key从 Json Web Key 获取公钥字节数组
【发布时间】:2018-07-04 23:19:48
【问题描述】:

我有一个包含公钥信息的 Json Web 密钥,我想将公钥作为字节数组获取。我的目标是最终使用 Keccak 哈希从中派生出以太坊地址。我了解从公钥字节数组中获取地址的过程,但是我不知道如何获取这个字节数组。我的方案是,使用 Azure Key Vault API 生成 EC 密钥,检索密钥(JWK 格式),然后找到地址。 JWK 具有以下格式。

{
  "kid": "https: //mykeyvault.vault.azure.net/keys/testeckey/8bad08aaae514efe981eaab4e590778d",
  "kty": "EC",
  "key_ops": [
    "sign",
    "verify"
  ],
  "crv": "P-256",
  "x": "YooqHyo7hlmcrBs5lDSSUsB0axzvorjxzNl6DBZLUf0",
  "y": "NM-JrV6NTbUgILY_sBm5VgYxt1zYccCOCFtSDicSfWM"
}

我正在使用 Azure .NET SDK,并且可以选择使用 Bouncy Castle for .NET 或任何 JS 库,因为项目也可以在 Node.js 环境中运行。如何获取公钥的字节数组? 谢谢

【问题讨论】:

    标签: .net ethereum public-key azure-keyvault jwk


    【解决方案1】:

    回答我自己的问题以防其他人需要。 我也写了一篇关于这个的文章,希望有人觉得它有用。

    https://tmarkovski.github.io/eth-azure/keyvault-part1/

    最初,我生成的密钥类型不正确。我能够通过连接来自 JWK 的 X 和 Y 数组来生成密钥。这是我在 F# 中使用的示例代码。它使用 BouncyCastle 作为 Keccak 哈希函数。 需要注意的重要一点是“EC-HSM”密钥类型的使用。这是 Key Vault 的高级 SKU 的一部分,只有这种类型支持 SECP256K1 曲线,否则如果使用“EC”密钥类型,则会引发异常。

    open Microsoft.Azure.KeyVault
    open System.Threading.Tasks
    open System
    open Microsoft.IdentityModel.Clients.ActiveDirectory
    open Microsoft.Azure.KeyVault.Models
    open Microsoft.Azure.KeyVault.WebKey
    open Org.BouncyCastle.Crypto.Digests
    open Org.BouncyCastle.Crypto
    
    /// Implements an extension method that overloads the standard
    /// 'Bind' of the 'async' builder. The new overload awaits on 
    /// a standard .NET task
    type AsyncBuilder with
      member __.Bind(t:Task<'T>, f:'T -> Async<'R>) : Async<'R>  = 
        async.Bind(Async.AwaitTask t, f)
    
    let vaultUri = "https://__mykeyvault__.vault.azure.net/"
    let clientId = "..."
    let clientSecret = "..."
    
    type AuthenticationCallback = KeyVaultClient.AuthenticationCallback
    
    let getAccessToken (authority:string) (resource:string) (scope:string) =    
        let clientCredential = new ClientCredential(clientId, clientSecret)
        let context = new AuthenticationContext(authority, TokenCache.DefaultShared)
        async {
            let! result = context.AcquireTokenAsync(resource, clientCredential)
            return result.AccessToken;
        } |> Async.StartAsTask
    
    let client = new KeyVaultClient(new KeyVaultCredential(new AuthenticationCallback(getAccessToken)))
    
    let createKey name =
        let keyParams = new NewKeyParameters()
        keyParams.Kty <- "EC-HSM"
        keyParams.CurveName <- EcKey.SECP256K1
    
        async {
            let! result = client.CreateKeyAsync(vaultUri, name, keyParams)
            return result
        } |> Async.RunSynchronously
    
    let getKey name = 
        async {
            let! result = client.GetKeyAsync(vaultBaseUrl = vaultUri, keyName = name)
            return result
        } |> Async.RunSynchronously
    
    let getPubKey (jwk:KeyBundle) = 
         Array.concat [| jwk.Key.X; jwk.Key.Y |]
    
    let hash (digest:IDigest) data =
        digest.Reset()
        digest.BlockUpdate(data, 0, data.Length)
    
        let a = digest.GetDigestSize() |> Array.zeroCreate
        digest.DoFinal(a, 0) |> ignore
        a
    
    let toHex (x:byte) = x.ToString("x2")
    
    let getAddress pubKey =
        pubKey
        |> hash (new KeccakDigest(256))
        |> Array.map toHex
        |> Array.skip 12
        |> String.Concat
        |> (+) "0x"
    
    
    createKey "testEcKey"
    |> getPubKey
    |> getAddress
    |> Console.WriteLine
    
    // 0x51e4370152c132d307c302d8146c63ca6bf41167
    

    【讨论】:

      猜你喜欢
      • 2019-06-10
      • 2015-05-16
      • 1970-01-01
      • 2016-12-28
      • 2013-05-26
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 2016-06-22
      相关资源
      最近更新 更多