检索的Base64 ECC公钥EN codeD字符串 [英] Retrieve ECC Public Key from Base64 encoded string

查看:629
本文介绍了检索的Base64 ECC公钥EN codeD字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图使用base64连接codeD ECC公钥创建 java.security.PublicKey 的一个实例。

MainActivity.java

  @覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);    尝试{
        字节[]数据=去codePublicKey(AsIAEFjzIcX + Kvhe8AmLoGUc8aYAEAwf5ecREGZ2u4RLxQuav / A =);
        公钥公钥= loadPublicKey(secp128r1的数据);        Log.d(TAG,publicKey.toString());
    }赶上(的SQLException | IOException异常| GeneralSecurityException E){
        Log.e(TAG,e.getMessage(),E);
    }
}私人字节[]德codePublicKey(String s)将抛出UnsupportedEncodingException {
    返回Base64.de code(S,Base64.DEFAULT);
}公共公钥loadPublicKey(字符串曲线,字节[]数据)
        抛出的SQLException,IOException异常,GeneralSecurityException {
    Log.d(TAG,Arrays.toString(数据));
    // [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,长度+将String.valueOf(data.length));    工厂的KeyFactory = KeyFactory.getInstance(EC,SC);
    ECNamedCurveParameterSpec规格= ECNamedCurveTable.getParameterSpec(曲线);
    ECCurve eccCurve = spec.getCurve();
    Log.d(TAG,曲线+曲线);    EllipticCurve ellipticCurve = EC5Util.convertCurve(eccCurve,spec.getSeed());    //解码点失败,
    //号线66。
    ECPoint点= ECPointUtil.de $ C $连接点(ellipticCurve,数据);
    ECParameterSpec PARAMS = EC5Util.convertSpec(ellipticCurve,规格);    ECPublicKeySpec keySpec =新ECPublicKeySpec(点,则params);
    返回factory.generatePublic(keySpec)根据;
}

logcat的:

 流程:com.example.eccdemo,PID:21151
了java.lang.RuntimeException:无法启动活动ComponentInfo {com.example.eccdemo / com.example.eccdemo.MainActivity}:java.lang.IllegalArgumentException异常:不正确的长度COM pressed编码
        在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2329)
        在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        在android.app.ActivityThread.access $ 900(ActivityThread.java:147)
        在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1296)
        在android.os.Handler.dispatchMessage(Handler.java:102)
        在android.os.Looper.loop(Looper.java:135)
        在android.app.ActivityThread.main(ActivityThread.java:5254)
        在java.lang.reflect.Method.invoke(本机方法)
        在java.lang.reflect.Method.invoke(Method.java:372)
        在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:898)
        在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
 java.lang.IllegalArgumentException异常:引起不正确的长度为COM pressed编码
        在org.spongycastle.math.ec.ECCurve.de $ C $口岸系统(ECCurve.java:349)
        在org.spongycastle.jce.ECPointUtil.de $ C $口岸系统(ECPointUtil.java:52)
        在com.example.eccdemo.MainActivity.loadPublicKey(MainActivity.java:66)
        在com.example.eccdemo.MainActivity.onCreate(MainActivity.java:45)
        在android.app.Activity.performCreate(Activity.java:5933)
        在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
        在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        在android.app.ActivityThread.access $ 900(ActivityThread.java:147)
        在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1296)
        在android.os.Handler.dispatchMessage(Handler.java:102)
        在android.os.Looper.loop(Looper.java:135)
        在android.app.ActivityThread.main(ActivityThread.java:5254)
        在java.lang.reflect.Method.invoke(本机方法)
        在java.lang.reflect.Method.invoke(Method.java:372)
        在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:898)
        在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)

进一步检查:

在logcat中,在打印德$ C $光盘字节,它们实际上是从在服务器上相差1:

  Log.d(TAG,Arrays.toString(数据));
    [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]

在蟒蛇控制台:

 在[131]:[_ _为在ap.public_key.tobytes()]
出[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]

这将是巨大的,如果有人可以解释的原因这个异常,也帮助我的小片段来从字符串公钥实例。

参考文献:


  • <一个href=\"http://www.programcreek.com/java-api-examples/index.php?api=org.bouncycastle.asn1.ASN1InputStream\" rel=\"nofollow\">http://www.programcreek.com/java-api-examples/index.php?api=org.bouncycastle.asn1.ASN1InputStream


  • <一个href=\"http://www.bouncycastle.org/wiki/display/JA1/Elliptic+Curve+Key+Pair+Generation+and+Key+Factories\" rel=\"nofollow\">http://www.bouncycastle.org/wiki/display/JA1/Elliptic+Curve+Key+Pair+Generation+and+Key+Factories


在此先感谢!

更新:

在尝试使用下面的一行来加载ASN1Primitive,它抛出以下异常:

  ASN1Primitive.fromByteArray(数据);

例外:

  java.io.IOException异常:DER长度超过4个字节:66
        在org.spongycastle.asn1.ASN1InputStream.readLength(ASN1InputStream.java:347)
        在org.spongycastle.asn1.ASN1InputStream.readLength(ASN1InputStream.java:112)
        在org.spongycastle.asn1.ASN1InputStream.readObject(ASN1InputStream.java:237)
        在org.spongycastle.asn1.ASN1Primitive.fromByteArray(ASN1Primitive.java:30)
        在com.example.eccdemo.MainActivity.onCreate(MainActivity.java:48)
        在android.app.Activity.performCreate(Activity.java:5933)
        在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
        在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2282)
        在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        在android.app.ActivityThread.access $ 900(ActivityThread.java:147)
        在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1296)
        在android.os.Handler.dispatchMessage(Handler.java:102)
        在android.os.Looper.loop(Looper.java:135)
        在android.app.ActivityThread.main(ActivityThread.java:5254)
        在java.lang.reflect.Method.invoke(本机方法)
        在java.lang.reflect.Method.invoke(Method.java:372)
        在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:898)
        在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)


解决方案

您的base64 EN codeD数据是38字节长,似乎并不在ASN1。也许这是一个问题。在只要你可以提取您的数据X和Y另一只手就可以生成公钥是这样的:

 字符串hexPubKeyXY =01f82bfb2f0a3e988adc3d053d8e6ff878154306e402d871b7d6000823a1397f;
      串海克斯= hexPubKeyXY.substring(0,32);
      串hexY = hexPubKeyXY.substring(32);
      ECPoint点=新ECPoint(新的BigInteger(海克斯,16),新的BigInteger(hexY,16));      的AlgorithmParameters参数= AlgorithmParameters.getInstance(EC,SunEC);
      parameters.init(新ECGenParameterSpec(secp128r1));
      ECParameterSpec为ECParameters = parameters.getParameterSpec(ECParameterSpec.class);      ECPublicKeySpec pubKeySpec =新ECPublicKeySpec(点,为ECParameters);      公钥密钥= KeyFactory.getInstance(EC,SunEC)generatePublic(pubKeySpec)。

I've been trying to create an instance of java.security.PublicKey using a Base64 encoded ECC public key.

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)

Further Inspection:

In Logcat, upon printing the decoded bytes, they actually differ from the one on the server:

    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]

In python console:

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]

It would be great if someone can explain the reason to this anomaly, and also help me out on the small snippet to get PublicKey instance from the String.

References:

Thanks in advance!!

Update:

When trying to load ASN1Primitive using the line below, it throws the following exception:

ASN1Primitive.fromByteArray(data);

Exception:

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)

解决方案

Your base64 encoded data is 38 bytes long and does not seem to be in ASN1. Maybe that is a problem. On another hand as long as you can extract X and Y from your data you can generate public key this way:

      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);

这篇关于检索的Base64 ECC公钥EN codeD字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆