EC密钥对生成Java代码与JavaKeyStore Explorer应用程序

EC密钥对生成Java代码与JavaKeyStore Explorer应用程序,java,cryptography,Java,Cryptography,我创建了一个密钥对EC NIST p-256,具有: [ 私钥的ASN.1格式如下所示: SEQUENCE { INTEGER=0 SEQUENCE { OBJECT IDENTIFIER=EcPublicKey (1.2.840.10045.2.1) OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7) } OCTET STRING, encapsulates: SEQUENCE { INTEGE

我创建了一个密钥对EC NIST p-256,具有:

[

私钥的ASN.1格式如下所示:

SEQUENCE
{
INTEGER=0
SEQUENCE
{
    OBJECT IDENTIFIER=EcPublicKey (1.2.840.10045.2.1)
    OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7)
}
OCTET STRING, encapsulates:
    SEQUENCE
    {
        INTEGER=1
        OCTET STRING=
            A3 6E C5 71 D3 15 F1 87   ÃnÅqÓ.õ.
            E9 BF AF 78 74 74 67 BC   é¿ xttg¼
            4D A0 69 BF 53 3A C2 E0   M i¿S:Âà
            D8 F6 F5 BC 2E C1 B4 CC   Øöõ¼..´Ì
        TAGGED [0]:
            OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7)
        TAGGED [1]:
            BIT STRING=
                E6 A9 E2 62 AB 3C 9E 43   ..^Ñ..)X
                E6 A9 E2 62 AB 3C 9E 43   #óþ[æEYî
                E6 A9 E2 62 AB 3C 9E 43   .h®Î..Ë5
                E6 A9 E2 62 AB 3C 9E 43   #óþ[æEYî
                E6 A9 E2 62 AB 3C 9E 43   &.^5.ù¥.
                E6 A9 E2 62 AB 3C 9E 43   #óþ[æEYî
                E6 A9 E2 62 AB 3C 9E 43   #óþ[æEYî
                E6 A9 E2 62 AB 3C 9E 43   .Ëkut.èö
                93                        .
    }

}
然后我试图通过代码实现同样的目标:

 private static final String KEY_BEGIN_PRIVATE = "-----BEGIN PRIVATE KEY-----\n";
 private static final String KEY_END_PRIVATE = "-----END PRIVATE KEY-----\n";

 private static void CreateCertificate(BigInteger serialNumber) throws Exception {

 //Create key
 KeyPairGenerator keypairGen = KeyPairGenerator.getInstance("EC");
 ECGenParameterSpec ecgenspec = new ECGenParameterSpec(curve); //curve = "NIST P-256"
 keypairGen.initialize(ecgenspec);
 KeyPair keypair = keypairGen.generateKeyPair()

 X500Name subject = CreateSubject(); 

 X509v3CertificateBuilder certificate = CreateCertificateBuilder(subject, 
 keypair.getPublic(), serialNumber);

 ContentSigner signer = new JcaContentSignerBuilder("SHA256withECDSA")
 .build(keypair.getPrivate());
 X509CertificateHolder holder = certificate.build(signer);

 JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
 converter.setProvider(new BouncyCastleProvider());
 X509Certificate x509 = converter.getCertificate(holder);

 // Encode to pem
 org.apache.commons.codec.binary.Base64 encoder = new 
 org.apache.commons.codec.binary.Base64(64);

 byte[] derKey = key.getEncoded();
 String pemKey = KEY_BEGIN_PRIVATE + encoder.encodeAsString(derKey) + KEY_END_PRIVATE;

 //Write to disk
 writer = null;
 File file = new File("somepath");
 file.createNewFile();
 writer = new BufferedWriter(new FileWriter(file));

 writer.write(pemKey);

 writer.close();
}
密钥创建工作正常,没有错误,但在ASN.1中密钥看起来不同,尽管算法相同。缺少标记的[1]部分

SEQUENCE
{
  INTEGER=0
  SEQUENCE
  {
    OBJECT IDENTIFIER=EcPublicKey (1.2.840.10045.2.1)
    OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7)
  }
  OCTET STRING, encapsulates:
    SEQUENCE
    {
        INTEGER=1
        OCTET STRING=
            66 28 18 9F 7C 34 7A 5B   f(..|4z[
            23 F3 FE 5B E6 45 59 EE   #óþ[æEYî
            E6 A9 E2 62 AB 3C 9E 43   æ©âb«<.C
            7B CC 8C 13 D1 26 3B 87   {Ì..Ñ&;.
        TAGGED [0]:
            OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7)
    }

}
在我看来,这与我如何创建密钥和证书有关,但告诉我我的基本编码错误的异常让我感到疑惑,因为密钥可以在导入时通过keystore explorer和openssl comand line很好地读取

我的问题是:

  • 代码中是否有一些愚蠢的错误或我做错的事情
  • java密钥库浏览器与我有什么不同
我尝试了不同的方法来使用不同的libs进行Base64编码,但是没有任何区别


附加:我无法访问读取密钥和证书的应用程序的源代码,因此我无法检查实现。但由于其他密钥有效,我假设错误在我这边。密钥不会在任何生产或测试场景中使用,因此在此处发布它们是安全的,我还修改了值,但这是错误的我不会对您造成任何影响。

所以我检查了我的代码并发现了错误。我只是忘记了在每个64位拆分编码字符串

我更改了密钥的编码方式,如下所示(见此处):


所以我检查了我的代码,发现了错误。我只是忘了在每个64位拆分编码字符串

我更改了密钥的编码方式,如下所示(见此处):


错误是应用程序需要base64数据,但无法获取该数据。由于您没有源代码,而且“d”是有效的base64字符,我只能猜测错误是指CR字符0x0d。请从base64数据中删除这些字符。可能会删除所有空白。可能会在
Java.util中使用Java base64编码器。您删除了一个依赖项,默认情况下它不会生成空白。错误是应用程序需要base64数据,但无法获取该数据。由于您没有源代码,而且“d”是有效的base64字符,我只能猜测错误是指CR字符0x0d。请从base64数据中删除这些数据。可能会获取清除所有空白。可能在
Java.util
中使用Java Base64编码器。删除一个依赖项,默认情况下它不会生成空白。
java.lang.IllegalArgumentException: Illegal base64 character d
private static String BaseEncode(byte[] data) {
    String encoded = Base64.encodeBase64String(data);
    String formatted="";
    for (String substring : Splitter.fixedLength(64).split(encoded)) {
        formatted += substring + "\n";
    }
    return formatted;
}