首页 > 解决方案 > AWS-KMS 中 ECC P256K1 的公钥是 88 字节?

问题描述

var kms = new AWS.KMS();

var pubKeyParam = {
  KeyId: 'xxxxxxxx', /* required */
};

kms.getPublicKey(pubKeyParam, function(err, data) {
  if (err) console.log(err, err.stack);
  else
      publicKey = data.PublicKey
      console.log(publicKey.length) <-- 88 bytes not 64 bytes 
});

提前感谢您的帮助

标签: aws-kms

解决方案


KMS 公钥解析

KMS 以 ASN.1 格式返回公钥。

如果您使用publicKeyFromAsn1此处转换密钥,它将返回 64 个字节:

import * as asn1js from 'asn1js';

function toArrayBuffer(buffer: Buffer): ArrayBuffer {
  const ab = new ArrayBuffer(buffer.length);
  const view = new Uint8Array(ab);
  for (let i = 0; i < buffer.length; ++i) {
    view[i] = buffer[i];
  }
  return ab;
}

// call this with your KMS public key
function publicKeyFromAsn1(buf: Buffer): Buffer {
  const { result } = asn1js.fromBER(toArrayBuffer(buf));
  const values = (result as asn1js.Sequence).valueBlock.value;
  const value = values[1] as asn1js.BitString;
  return Buffer.from(value.valueBlock.valueHex.slice(1));
}

KMS 签名解析

KMS 签名采用 DER 格式(这是有效的 BER)。它最终看起来像这样:30440220{r}0220{s} 这是一些帮助您提取 r & s 的解析逻辑。

import * as asn1js from 'asn1js';

function toArrayBuffer(buffer: Buffer): ArrayBuffer {
  const ab = new ArrayBuffer(buffer.length);
  const view = new Uint8Array(ab);
  for (let i = 0; i < buffer.length; ++i) {
    view[i] = buffer[i];
  }
  return ab;
}

//call this with your signature buffer
function parseBERSignature(sig: Buffer): { r: Buffer; s: Buffer } {
  const { result } = asn1js.fromBER(toArrayBuffer(sig));
  const part1 = (result as asn1js.Sequence).valueBlock.value[0] as asn1js.BitString;
  const part2 = (result as asn1js.Sequence).valueBlock.value[1] as asn1js.BitString;

  return {
    r: Buffer.from(part1.valueBlock.valueHex),
    s: Buffer.from(part2.valueBlock.valueHex),
  };
}

推荐阅读