Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从未压缩的客户端临时公钥和开放SSL静态服务器私钥生成ECPublicKey/ECPrivateKey时出错_Java_Cryptography_Bouncycastle_Shared Secret - Fatal编程技术网

Java 从未压缩的客户端临时公钥和开放SSL静态服务器私钥生成ECPublicKey/ECPrivateKey时出错

Java 从未压缩的客户端临时公钥和开放SSL静态服务器私钥生成ECPublicKey/ECPrivateKey时出错,java,cryptography,bouncycastle,shared-secret,Java,Cryptography,Bouncycastle,Shared Secret,希望在这里得到一些帮助 我试图从未压缩的客户端公钥(0x04 | 32字节点X | 32字节点Y)和服务器私钥(openSSL生成的base64)生成共享密钥,但在将服务器EC私钥转换为EC密钥对象时出错。我需要这些来生成共享秘密 我正在使用- 1.曲线为P256R1 2.服务器私钥是使用openSSL生成的(目前在代码中是硬编码的) 3.客户端公共以未压缩格式共享(格式0x04 | 32字节点X | 32字节点Y) 错误 2018-02-26 14:31:12.818[0;39m [31mER

希望在这里得到一些帮助

我试图从未压缩的客户端公钥(0x04 | 32字节点X | 32字节点Y)和服务器私钥(openSSL生成的base64)生成共享密钥,但在将服务器EC私钥转换为EC密钥对象时出错。我需要这些来生成共享秘密

我正在使用- 1.曲线为P256R1 2.服务器私钥是使用openSSL生成的(目前在代码中是硬编码的) 3.客户端公共以未压缩格式共享(格式0x04 | 32字节点X | 32字节点Y)

错误

2018-02-26 14:31:12.818[0;39m [31mERROR[0;39m [35m18096[0;39m [2m---[0;39m [2m[nio-8080-exec-1][0;39m [36mo.a.c.c.C.[.[.[/].[dispatcherServlet]   [0;39m [2m:[0;39m Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.security.spec.InvalidKeySpecException: java.lang.IllegalArgumentException: wrong version for private key info] with root cause

java.security.spec.InvalidKeySpecException: java.lang.IllegalArgumentException: wrong version for private key info
    at org.bouncycastle.jce.provider.JDKKeyFactory$EC.engineGeneratePrivate(Unknown Source) ~[bcprov-jdk15-140.jar:1.40.0]
    at java.security.KeyFactory.generatePrivate(KeyFactory.java:366) ~[na:1.8.0_77]

TLDR:该私钥不是PKCS8

OpenSSL支持每种算法四种不同的PEM私钥格式(总共大约十二种);其中只有一种是PKCS8 unencrypted,这是Java PKCS8EncodedKeySpec所要求的格式,您使用的是另一种Java不支持的格式。与RSA的比较;对于EC,这两种“传统”格式由SEC1 from定义(对于RSA,则由PKCS1定义),而PKCS8格式(对于所有算法,而不仅仅是EC和RSA),则由PKCS8定义。OpenSSL能够处理多种格式,主要是因为PEM文件有一个非常重要的开始行(不太重要的结束行)来指定数据类型;删除文件之前,文件的类型为
EC PRIVATE KEY
表示SEC1而不是type
PRIVATE KEY
表示Java使用的PKCS8未加密

您有两个(或更多)选项:

  • 使用
    OpenSSL-PKCS8-topk8-nocrypt
    或只是
    OpenSSL-pkey
    (在1.0.0以上版本中)将OpenSSL密钥转换为PKCS8未加密的PEM,或者首先使用
    genpkey
    或可能的
    req-newkey
    (在1.0.0以上版本中)而不是
    ecparam-genkey
    将其生成为PKCS8。在PKCS8EncodedKeySpec中使用该blob de-base64-ed

  • 如果除了bcprov之外,您还拥有或获得了bcpkix,那么它可以处理许多(可能全部?)OpenSSL格式,而普通Java无法处理这些格式。重新生成或恢复为原始PEM格式(可存储在内存中),您可以使用
    PEMReader
    进行解析,然后使用
    JcaPEMKeyConverter
    (或仅使用
    KeyFactory
    )进行转换

这两个都包含在for RSA中,可以很容易地针对EC进行修改

  • 或者,由于您已经完成了PEM解析的一部分,因此您可以按照
    PEMParser
    所做的相同方式自己处理其余部分,仅对私有部分进行简化:
导入java.security.*; 导入org.bouncycastle.asn1.asn1序列; 导入org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 导入org.bouncycastle.asn1.x509.AlgorithmIdentifier; 导入org.bouncycastle.asn1.x9.X9ObjectIdentifiers; ... 静态void SO48996981BCparseECprivate()引发异常{ byte[]server_sec1=DatatypeConverter.ParseBase64二进制(“MHGCAQEEI27NM1KLJ9PVXOZJRO4ABLFXTTOJNF+vMhiv3HA+3NOASGCSSKAWMCCAEBB6FEA0IABG1ERLYTBC5YN8GVY4A0JPO5EEFKWMBSQIJ2KS5TANUJ/tqigFqsk1g/l2UBBkIx2KdpeiY8nVddwMpzho=”); ASN1Sequence seq=ASN1Sequence.getInstance(服务器_sec1); org.bouncycastle.asn1.sec.ECPrivateKey pKey=org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq); AlgorithmIdentifier algId=新算法标识符(X9ObjectIdentifiers.id_ecPublicKey,pKey.getParameters()); byte[]server_pkcs8=new PrivateKeyInfo(algId,pKey).getEncoded(); KeyFactory事实=KeyFactory.getInstance(“EC”、“BC”); PrivateKey pkey=fact.generatePrivate(新的PKCS8EncodedKeySpec(server_pkcs8)); //仅用于测试: System.out.println(pkey.getClass().getName()+“”+pkey.getAlgorithm()); }
  • 最后,您并不需要Java来实现这一点。OpenSSL可以在库中(从您编写的代码调用)或命令行中执行ECDH密钥协商/派生,但对于后者,您需要PEM文件中的密钥:OpenSSL支持的任何PEM格式的私钥(您已经拥有),但X.509 SubjectPublicKeyInfo格式的对等公钥,根据您提供的信息,您可能不需要也可能需要构建

  • TLDR:该私钥不是PKCS8

    OpenSSL支持每种算法四种不同的PEM私钥格式(总共大约十二种);其中只有一种是PKCS8 unencrypted,这是Java PKCS8EncodedKeySpec所要求的格式,您使用的是另一种Java不支持的格式。与RSA的比较;对于EC,这两种“传统”格式由SEC1 from定义(对于RSA,则由PKCS1定义),而PKCS8格式(对于所有算法,而不仅仅是EC和RSA),则由PKCS8定义。OpenSSL能够处理多种格式,主要是因为PEM文件有一个非常重要的开始行(不太重要的结束行)来指定数据类型;删除文件之前,文件的类型为
    EC PRIVATE KEY
    表示SEC1而不是type
    PRIVATE KEY
    表示Java使用的PKCS8未加密

    您有两个(或更多)选项:

    • 使用
      OpenSSL-PKCS8-topk8-nocrypt
      或只是
      OpenSSL-pkey
      (在1.0.0以上版本中)将OpenSSL密钥转换为PKCS8未加密的PEM,或者首先使用
      genpkey
      或可能的
      req-newkey
      (在1.0.0以上版本中)而不是
      ecparam-genkey
      将其生成为PKCS8。在PKCS8EncodedKeySpec中使用该blob de-base64-ed

    • 如果除了bcprov之外,您还拥有或获得了bcpkix,那么它可以处理许多(可能全部?)OpenSSL格式,而普通Java无法处理这些格式。重新生成或恢复为原始PEM格式(可存储在内存中),您可以使用
      PEMReader
      进行解析,然后使用
      JcaPEMKeyConverter
      (或仅使用
      KeyFactory
      )进行转换

    这两个都包含在for RSA中,可以很容易地针对EC进行修改

    • 或者,因为您已经完成了PEM解析的一部分,所以您可以自己处理其余部分
      2018-02-26 14:31:12.818[0;39m [31mERROR[0;39m [35m18096[0;39m [2m---[0;39m [2m[nio-8080-exec-1][0;39m [36mo.a.c.c.C.[.[.[/].[dispatcherServlet]   [0;39m [2m:[0;39m Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.security.spec.InvalidKeySpecException: java.lang.IllegalArgumentException: wrong version for private key info] with root cause
      
      java.security.spec.InvalidKeySpecException: java.lang.IllegalArgumentException: wrong version for private key info
          at org.bouncycastle.jce.provider.JDKKeyFactory$EC.engineGeneratePrivate(Unknown Source) ~[bcprov-jdk15-140.jar:1.40.0]
          at java.security.KeyFactory.generatePrivate(KeyFactory.java:366) ~[na:1.8.0_77]
      
      import java.security.*; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; ... static void SO48996981BCparseECprivate () throws Exception { byte[] server_sec1 = DatatypeConverter.parseBase64Binary("MHgCAQEEIA27nM1klj9pVxOzJrO4aBLFvXTtOJnf+vMhiv3HA+3noAsGCSskAwMCCAEBB6FEA0IABG1erLtLyTbC5yN8gVY4a0JPO5eefKftWMbSQij2Ks5TaNNuj/tqigFqsk1g/l2UBBkIx2KdpeiY8nVddwMpzho="); ASN1Sequence seq = ASN1Sequence.getInstance(server_sec1); org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq); AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParameters()); byte[] server_pkcs8 = new PrivateKeyInfo(algId, pKey).getEncoded(); KeyFactory fact = KeyFactory.getInstance ("EC","BC"); PrivateKey pkey = fact.generatePrivate (new PKCS8EncodedKeySpec(server_pkcs8)); // for test only: System.out.println (pkey.getClass().getName() + " " + pkey.getAlgorithm()); }