无论是使用keytool
还是普通Java代码,使用椭圆曲线创建签名对于我来说都不适用于Java 1.7.0_85
。
例如 - 使用keytool
在NIST P-256曲线上生成新的EC密钥:
keytool -v -genkeypair -alias my_key -keyalg EC -keysize 256 -keystore test.jks
抛出以下异常:
keytool error: java.security.SignatureException: Could not sign data
java.security.SignatureException: Could not sign data
at sun.security.ec.ECDSASignature.engineSign(ECDSASignature.java:297)
at java.security.Signature$Delegate.engineSign(Signature.java:1205)
at java.security.Signature.sign(Signature.java:578)
at sun.security.x509.X509CertImpl.sign(X509CertImpl.java:524)
at sun.security.x509.X509CertImpl.sign(X509CertImpl.java:474)
at sun.security.x509.CertAndKeyGen.getSelfCertificate(CertAndKeyGen.java:269)
at sun.security.tools.KeyTool.doGenKeyPair(KeyTool.java:1558)
at sun.security.tools.KeyTool.doCommands(KeyTool.java:969)
at sun.security.tools.KeyTool.run(KeyTool.java:340)
at sun.security.tools.KeyTool.main(KeyTool.java:333)
Caused by: java.security.KeyException
at sun.security.ec.ECDSASignature.signDigest(Native Method)
at sun.security.ec.ECDSASignature.engineSign(ECDSASignature.java:293)
... 9 more
由于这是一个非常低级别的异常,因此无论我想在Java代码中使用EC签名,都会抛出相同的异常。
我检查了我的java.security
文件是否安装了SunEC
提供程序,但一切都很好看:
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=sun.security.ec.SunEC
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
以及JAVA_HOME/jre/lib/ext/
包含sunec.jar
。
此外,US_export_policy.jar
和local_policy.jar
位于JAVA_HOME/jre/lib/security
文件夹中。
任何想法可能是什么原因? ECC应该与Java 7一起使用。
编辑:这里也是用于生成与keytool
相同的异常的Java代码 - 我使用略有不同的情况 - 使用EC P-256转换的PKCS12证书密钥到JKS密钥库。在最后一行调用sign()
方法时抛出异常。
KeyStore kst = KeyStore.getInstance("JKS");
kst.load(new FileInputStream("kst.jks"), "******".toCharArray());
Key k = kst.getKey("my_key", "******".toCharArray());
Signature sig = Signature.getInstance("SHA256withECDSA");
sig.initSign((PrivateKey)k);
sig.update("test".getBytes());
System.out.println(bytesToHex(sig.sign()));