【问题标题】:Convert P-256 DH java string to java PublicKey将 P-256 DH java 字符串转换为 java PublicKey
【发布时间】:2017-04-06 03:15:34
【问题描述】:

我正在尝试将网络推送通知发送到我的浏览器并且能够成功订阅。我得到一个带有“P-256 曲线上的椭圆曲线 Diffie-Hellman 公钥”的订阅对象。

我想将此字符串转换为 Java 中的公钥,但不断收到无效的密钥格式异常。

这是我正在尝试的代码:

  String publicK = "BBoN_OkTfE_0uObues82qHr96z8x3nepYoUwCBoftFDS_Vgx2MUHN1vAFxc1eDiyDrvmZ2bQ4sJq3F8Qz71RWI0=";
  byte[] publicBytes = publicK.getBytes();
  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
  KeyFactory keyFactory = KeyFactory.getInstance("DiffieHellman");
  PublicKey pubKey = keyFactory.generatePublic(keySpec);

有人可以帮我解决这个问题吗?加密菜鸟在这里:/

【问题讨论】:

    标签: java diffie-hellman


    【解决方案1】:

    对于我的代码,我使用了 java 1.7BouncyCastle 库。如果您使用 maven,只需添加到您的 pom.xml

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk16</artifactId>
        <version>1.46</version>
    </dependency>
    

    或者在BouncyCastle 站点下载jar。这是一个用于 java 的密码学 API,有很多有用的东西(包括处理椭圆曲线密钥的类)。

    读取公钥并转换为对象的代码为:

    import java.security.KeyFactory;
    import java.security.Security;
    import java.security.interfaces.ECPublicKey;
    import java.security.spec.ECPoint;
    import java.security.spec.ECPublicKeySpec;
    
    import org.bouncycastle.jce.ECNamedCurveTable;
    import org.bouncycastle.jce.ECPointUtil;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
    import org.bouncycastle.jce.spec.ECNamedCurveSpec;
    import org.bouncycastle.util.encoders.Base64;
    
    
    // you need to add the BouncyCastle provider to use its functionalities
    Security.addProvider(new BouncyCastleProvider());
    
    String publicK = "BBoN_OkTfE_0uObues82qHr96z8x3nepYoUwCBoftFDS_Vgx2MUHN1vAFxc1eDiyDrvmZ2bQ4sJq3F8Qz71RWI0=";
    // publicK is encoded in base64, so you need to decode it first
    byte[] publicBytes = Base64.decode(publicK.getBytes());
    
    // spec for P-256 curve
    ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("prime256v1");
    // create a KeyFactory with ECDSA (Elliptic Curve Diffie-Hellman) algorithm and use BouncyCastle as the provider
    KeyFactory kf = KeyFactory.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);
    
    // code below just creates the public key from the bytes contained in publicK
    // using the curve parameters (spec variable)
    ECNamedCurveSpec params = new ECNamedCurveSpec("prime256v1", spec.getCurve(), spec.getG(), spec.getN());
    ECPoint point = ECPointUtil.decodePoint(params.getCurve(), publicBytes);
    ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(point, params);
    ECPublicKey pk = (ECPublicKey) kf.generatePublic(pubKeySpec);
    
    System.out.println(pk.toString());
    

    输出:

    EC Public Key
                X: 1a0d00e9137c4034b8e6ee7acf36a87afdeb3f31de77a9628530081a1fb450d2
                Y: 15831d8c507375bc01717357838b20ebbe66766d0e2c26adc5f10cfbd51588d
    

    注意事项

    • 我不知道椭圆曲线键背后的所有数学知识,只是基本概念。我知道曲线具有Gn 之类的参数(通过getG()getN() 方法获得),并且您可以使用一些“标准预定义”曲线(如P-256)开始使用ECNamedCurveTable.getParameterSpec()

    • 如果需要,您可以查看所有 math details。还有一个list of different standard curves,哪些被认为是安全的。

    • ECPublicKey 扩展了PublicKey,因此您可以像使用PublicKey 一样使用它

    【讨论】:

    • 非常感谢。这确实有效,但你能否给出一个简短的理论解释,以便我理解我在做什么?
    • 不客气。我不是数学/加密专家,但我在答案中添加了一些 cmets。如果您需要更多信息,请告诉我。
    猜你喜欢
    • 2020-12-01
    • 2018-10-20
    • 2023-03-17
    • 2013-01-29
    • 2016-08-06
    • 2012-06-09
    • 2011-01-08
    • 2018-11-29
    • 2011-11-29
    相关资源
    最近更新 更多