6

我需要使用 Java/Android 和在 .Net 环境中创建的 ATEC108A 芯片验证签名。(使用 SunEC 和 AndroidOpenSSL)

签名使用 BCrypt 在 .Net 中创建,密钥也使用 BCrypt 创建并存储在 Microsoft 密钥库中。签名和公钥可以发送到 AT 芯片并进行验证,但它不适用于 Android。

密钥/签名过程:

  1. 公钥以 x.509 密钥格式从 BCrypt 导出,其中包括 SHA256-ECDSA 的标识符和曲线 prime256v1,导致:

    3059301306072A8648CE3D020106082A
     8648CE3D03010703420004368711132B
     BDB4C6D03F7DF4F4688F5F4F21A3B30B
     EB1016648555A25B27C915CAB5C26B98
     0FF792A0090BF1E131C175D9C66C8D79
     3476489770869E09273816
  2. BCrypt 的签名是 64 字节格式,但 android 需要序列和长度标识符,从而导致签名如下:

    304502201
     BD91B39A7447724223A4B3E9070A6FD5
     33360F96B072998058AA73E572F48D80
     22100
     ED0BDC731080CFC82C8B8FB37D74CC18
     3820343C2756671F0E1D813E469DD3D7
  3. 用于签名和验证的消息是“Hello World”,其散列为:

    A591A6D40BF420404A011733CFB7B190
     D62C65BF0BCDA32B57B277D9AD9F146E

安卓进程:

  1. 从上述密钥字节数组创建 X509 密钥规范和公钥:

    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
     KeyFactory kf = KeyFactory.getInstance("EC", "AndroidOpenSSL");
     pubKey = kf.generatePublic(keySpec);
  2. 使用 AndroidOpenSSL 提供程序创建签名:

    签名签名;
     签名 = Signature.getInstance("SHA256withECDSA", "AndroidOpenSSL");
     签名.initVerify(pubKey);
  3. 加载上面的哈希数组:

    签名.更新(哈希);
  4. 验证上述签名:

    签名。验证(签名);

上面的签名和密钥在 AT 芯片上签出(也在运行 JavaScript-OpenSSL 的 ECDSA 示例上验证),但未通过 AndroidOpenSSL 验证。我错过了一些简单的东西还是问题出在哪里?

公钥结构在 ASN.1 解码器上检查并在代码中成功加载(从公钥中提取和检查),签名采用 Java 的预期格式,并且两侧的哈希值相同。

4

0 回答 0