从 Base64 编码字符串中检索 ECC 公钥

2023-11-30

我一直在尝试创建一个实例java.security.PublicKey使用 Base64 编码的 ECC 公钥。

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    try {
        byte[] data = decodePublicKey("AsIAEFjzIcX+Kvhe8AmLoGUc8aYAEAwf5ecREGZ2u4RLxQuav/A=");
        PublicKey publicKey = loadPublicKey("secp128r1", data);

        Log.d(TAG, publicKey.toString());
    } catch (SQLException | IOException | GeneralSecurityException e) {
        Log.e(TAG, e.getMessage(), e);
    }
}

private byte[] decodePublicKey(String s) throws UnsupportedEncodingException {
    return Base64.decode(s, Base64.DEFAULT);
}

public PublicKey loadPublicKey(String curve, byte[] data)
        throws SQLException, IOException, GeneralSecurityException {
    Log.d(TAG, Arrays.toString(data));
    // [2, -62, 0, 16, 88, -13, 33, -59, -2, 42, -8, 94, -16, 9, -117, -96, 101, 28, -15, -90, 0, 16, 12, 31, -27, -25, 17, 16, 102, 118, -69, -124, 75, -59, 11, -102, -65, -16]
    Log.d(TAG, "Length :" + String.valueOf(data.length));

    KeyFactory factory = KeyFactory.getInstance("EC", "SC");
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curve);
    ECCurve eccCurve = spec.getCurve();
    Log.d(TAG, "Curve: " + curve);

    EllipticCurve ellipticCurve = EC5Util.convertCurve(eccCurve, spec.getSeed());

    // decoding point fails, 
    // line no 66.
    ECPoint point = ECPointUtil.decodePoint(ellipticCurve, data);
    ECParameterSpec params = EC5Util.convertSpec(ellipticCurve, spec);

    ECPublicKeySpec keySpec = new ECPublicKeySpec(point, params);
    return factory.generatePublic(keySpec);
}

Logcat:

Process: com.example.eccdemo, PID: 21151
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.eccdemo/com.example.eccdemo.MainActivity}: java.lang.IllegalArgumentException: Incorrect length for compressed encoding
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2329)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        at android.app.ActivityThread.access$900(ActivityThread.java:147)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
 Caused by: java.lang.IllegalArgumentException: Incorrect length for compressed encoding
        at org.spongycastle.math.ec.ECCurve.decodePoint(ECCurve.java:349)
        at org.spongycastle.jce.ECPointUtil.decodePoint(ECPointUtil.java:52)
        at com.example.eccdemo.MainActivity.loadPublicKey(MainActivity.java:66)
        at com.example.eccdemo.MainActivity.onCreate(MainActivity.java:45)
        at android.app.Activity.performCreate(Activity.java:5933)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        at android.app.ActivityThread.access$900(ActivityThread.java:147)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)

进一步检查:

在 Logcat 中,在打印解码后的字节时,它们实际上与服务器上的不同:

    Log.d(TAG, Arrays.toString(data));
    [2, -62, 0, 16, 88, -13, 33, -59, -2, 42, -8, 94, -16, 9, -117, -96, 101, 28, -15, -90, 0, 16, 12, 31, -27, -25, 17, 16, 102, 118, -69, -124, 75, -59, 11, -102, -65, -16]

在 python 控制台中:

In [131]: [_ for _ in ap.public_key.tobytes()]
Out[131]: [2, 194, 0, 16, 88, 243, 33, 197, 254, 42, 248, 94, 240, 9, 139, 160, 101, 28, 241, 166, 0, 16, 12, 31, 229, 231, 17, 16, 102, 118, 187, 132, 75, 197, 11, 154, 191, 240]

如果有人能解释这个异常的原因,并帮助我解决这个小片段,那就太好了PublicKey来自字符串的实例。

参考:

  • http://www.programcreek.com/java-api-examples/index.php?api=org.bouncycastle.asn1.ASN1InputStream

  • http://www.bouncycastle.org/wiki/display/JA1/Elliptic+Curve+Key+Pair+Generation+and+Key+Factories

提前致谢!!

Update:

当尝试使用下面的行加载 ASN1Primitive 时,它​​会抛出以下异常:

ASN1Primitive.fromByteArray(data);

例外:

java.io.IOException: DER length more than 4 bytes: 66
        at org.spongycastle.asn1.ASN1InputStream.readLength(ASN1InputStream.java:347)
        at org.spongycastle.asn1.ASN1InputStream.readLength(ASN1InputStream.java:112)
        at org.spongycastle.asn1.ASN1InputStream.readObject(ASN1InputStream.java:237)
        at org.spongycastle.asn1.ASN1Primitive.fromByteArray(ASN1Primitive.java:30)
        at com.example.eccdemo.MainActivity.onCreate(MainActivity.java:48)
        at android.app.Activity.performCreate(Activity.java:5933)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        at android.app.ActivityThread.access$900(ActivityThread.java:147)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)

你的base64编码数据是38字节长,并且似乎不在ASN1中。也许这是一个问题。另一方面,只要您可以从数据中提取 X 和 Y,您就可以通过以下方式生成公钥:

      String hexPubKeyXY = "01f82bfb2f0a3e988adc3d053d8e6ff878154306e402d871b7d6000823a1397f";
      String hexX = hexPubKeyXY.substring(0, 32);
      String hexY = hexPubKeyXY.substring(32);
      ECPoint point = new ECPoint(new BigInteger(hexX, 16), new BigInteger(hexY, 16));

      AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC", "SunEC");
      parameters.init(new ECGenParameterSpec("secp128r1"));
      ECParameterSpec ecParameters = parameters.getParameterSpec(ECParameterSpec.class);

      ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, ecParameters);

      PublicKey key = KeyFactory.getInstance("EC", "SunEC").generatePublic(pubKeySpec);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 Base64 编码字符串中检索 ECC 公钥 的相关文章

随机推荐

  • R 计算 for 循环中的平均值

    我有我的代码 V max 10 V min 0 n 1 H 1 C c 0 0 01 0 1 1 par mfrow c length C 1 1 mar c 2 0 2 0 oma c 1 5 0 0 V lt function C H
  • 桌面 DLL 中的 Prism PopupChildWindowAction 缺失

    我正在尝试在 WPF Prism 桌面应用程序中实现模式对话框 从 Prism 指导中我可以看到正确的方法应该是使用交互
  • Xamarin Forms - 在运行时翻译抽屉菜单项

    我正在遵循优秀的教程 Link 关于 Xamarin Forms 中的多语言 一切正常 但我有一个问题 在我的应用程序中 我使用 Syncfusion 的导航抽屉 因为我在 ListView 中生成菜单项 如下所示 DrawerPage x
  • 批处理脚本未按预期分配变量

    我正在编写一个批处理脚本 它将分配一个变量字符串 然后修剪它 我面临两个问题 变量分配不正确 它从变量文件中获取最后一个值 我第一次运行脚本时未分配变量 我需要第二次运行脚本以查看变量是否已分配 在第三次运行时 我可以看到修剪正在起作用 我
  • 将数据帧中的字符转换为时间戳

    我在数据框中有一个被识别为字符类的时间戳 由于某种原因 我无法将其转换为 poxis 时间戳 这是数据示例 ID dateTime stage 1 2016 11 01T00 00 00 000Z 4 82 2 2016 11 01T00
  • 如何使 Text::slug() 正确转换德语变音符号?

    我正在使用 CakePHP 3 6 当我使用带有德语变音符号的单词时 例如 Text slug Grundst cke 我会得到 Grundstucke 其中 u 但这是不正确的 我应该得到 Grundstuecke 其中 ue 是否有一个
  • 将整数数组传递给 ASP.NET Web API?

    我有一个 ASP NET Web API 版本 4 REST 服务 我需要在其中传递一个整数数组 这是我的操作方法 public IEnumerable
  • 多个 Mat Paginator 无法在 Angular 组件中工作

    我有三个不同的 div Post Todo User 根据用户选择我显示不同的表格 例如 默认情况下Post部分加载表100 records 如果用户选择Todo部分 表格应显示Todo记录等带有分页 I ve three datasour
  • R tableGrob 更改行的格式

    我有一些相对简单的代码来创建用于打印到 PDF 的表格 library gridExtra df lt head iris tableGrob df gp gpar fontsize 8 rows NULL 我想让最后一行的格式与标题行相同
  • 使用 Windows 批处理文件的单行多个命令

    我尝试了解批处理文件中单个命令行中的多个命令如何工作 dir md folder1 rename folder1 mainfolder 和其他具有类似命令的情况 但是 替换为 dir md folder1 rename folder1 ma
  • 为什么 Microsoft Azure(或一般的 Swift)无法更新变量以在表查询后返回?

    我一直在关注微软Azure文档成功查询表 将项目插入 读取和更新到数据库中工作正常 但在一个简单的方法结束时 立即关闭文档 func getAllEventIDs gt String var events String this is to
  • 基于 Django 类的 UpdateView 以及用于多个上传文件的表单

    针对我目前面临的问题 我有两个问题 django 中的最佳实践是覆盖 CreateView 中的 post 方法吗 如果不是 您是否在 CategoryFullForm 或 CreateView 中编写 form valid 函数 它会是什
  • 名称查找和类范围

    为什么setVal的返回类型是string类型 参数类型是double类型 typedef string Type Type initVal class Exercise public typedef double Type Type se
  • Ember renderTemplate 中继模型

    在这里努力开发我的 Ember 应用程序 一切进展顺利 但是 我遇到了意外行为的问题 并且不确定解决此问题的最佳方法 问题是在特定路线中 我想将另一条路线渲染到另一个出口 但是 我渲染到另一个出口的另一条路线并不保留它自己的模型 如果我这样
  • 如何在 Tensorflow 中将变量重用设置回 False?

    在Tensorflow中 我们可以将变量重用设置为True with tf get variable scope reuse variables 有什么方法可以在不离开范围的情况下将其设置回 False 吗 这不可能 在共享变量的教程中 他
  • 如何在 Linux 中转义 scp 复制路径中的空格?

    我想将文件从远程复制到本地系统 现在我在linux系统中使用scp命令 我有一些文件夹或文件名带有空格 当我尝试复制该文件时 它显示错误消息 没有这样的文件或目录 I tried scp email protected home 5105
  • Laravel 4 - 分页忽略 Fluent 中的不同

    我以清晰和分页的方式提出流畅的请求 我的问题是分页请求在不同的请求之前执行 我的流利要求 candidates DB table candidates gt select candidates gt distinct gt join can
  • 如何使 For-Each 循环向后运行

    我用 VBA 编写了一个小脚本 它根据列表检查给定范围内的单元格的值 如果单元格值与列表中的值匹配 则保留该单元格值 否则将其删除 我想知道如何让它向后运行 因为向前运行会产生问题 我对此进行了一些研究 并尝试将 Step 1 附加到开始
  • Matlab神经网络,如何强制使用某些集合进行训练、验证和测试?

    如果您使用 GUI nnstart 则仅提供输入和输出 但您无法决定哪些行将作为训练 验证和测试集 因为它们是随机选择的 如何手动指定它们 您可以使用从 NNSTART 启动的任何 GUI 来创建一些示例训练代码 然后通过设置以下数据划分值
  • 从 Base64 编码字符串中检索 ECC 公钥

    我一直在尝试创建一个实例java security PublicKey使用 Base64 编码的 ECC 公钥 MainActivity java Override protected void onCreate Bundle savedI