我正在使用椭圆曲线算法生成用于签名的KeyPair。生成私钥后,我将其存储在KeyStore中并将其写入文件。当我调用Key.getAlgorithm时,它返回“ECDSA”。但是在从文件重新加载KeyStore之后,Key.getAlgorithm返回“EC”。我想知道这是从哪里来的,以及为什么我在保存后会得到不同的结果。
这是我的代码(请注意,为此需要在jre中安装JCE无限强度策略文件):
public static void main(String [] args) throws Exception
{
String PROVIDER = "BC";
String KEY_ALGORITHM = "ECDSA";
String SIGNATURE_ALGORITHM = "SHA1WITHECDSA";
String ALIAS = "TestAlias";
char [] PASSWORD = "password".toCharArray();
String KEYSTORE = "c:/test/bugs/keystore.p12";
Security.addProvider(new BouncyCastleProvider());
// Generate the key
Calendar calNow = Calendar.getInstance();
Calendar calLater = Calendar.getInstance();
calLater.set(Calendar.YEAR, calLater.get(Calendar.YEAR) + 25);
Date startDate = new Date(calNow.getTimeInMillis());
Date expiryDate = new Date(calLater.getTimeInMillis());
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp192r1");
KeyPairGenerator g = KeyPairGenerator.getInstance(KEY_ALGORITHM, PROVIDER);
g.initialize(ecSpec, new SecureRandom());
KeyPair keyPair = g.generateKeyPair();
X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
X500Principal dnName = new X500Principal("CN=Test");
certGen.setSerialNumber(new BigInteger(8, new SecureRandom()));
certGen.setIssuerDN(dnName);
certGen.setNotBefore(startDate);
certGen.setNotAfter(expiryDate);
certGen.setSubjectDN(dnName); // note: same as issuer
certGen.setPublicKey(keyPair.getPublic());
certGen.setSignatureAlgorithm(SIGNATURE_ALGORITHM);
X509Certificate cert = certGen.generate(keyPair.getPrivate(), PROVIDER);
// Save the keystore
KeyStore exportStore = KeyStore.getInstance("PKCS12", PROVIDER);
exportStore.load(null, null);
exportStore.setKeyEntry(ALIAS, keyPair.getPrivate(), PASSWORD, new Certificate[] { cert });
FileOutputStream out = new FileOutputStream(KEYSTORE);
exportStore.store(out, PASSWORD);
out.flush();
out.close();
// print the info from the keystore
System.out.println(exportStore.getKey(ALIAS, PASSWORD).getAlgorithm());
// Reload the keystore
FileInputStream in = new FileInputStream(KEYSTORE);
exportStore.load(in, PASSWORD);
in.close();
// print the info from the reloaded keystore
System.out.println(exportStore.getKey(ALIAS, PASSWORD).getAlgorithm());
}
基于this example from Bouncy Castle,在生成KeyPair时使用“ECDSA”似乎是正确的。
答案 0 :(得分:1)
Oracle
使用椭圆曲线密码术(ECDSA,ECDH,ECDHE,ECDH_anon)的密码套件需要符合以下要求的JCE加密提供程序:
提供程序必须实现由java.security.spec和java.security.interfaces包中的类和接口定义的ECC。 椭圆曲线键对象的getAlgorithm()方法必须返回字符串" EC"。
提供者必须支持签名算法SHA1withECDSA和NONEwithECDSA,KeyAgreement算法ECDH,以及KeyPairGenerator和算法EC的KeyFactory。如果缺少其中一种算法,SunJSSE将不允许使用EC密码套件。
提供者必须支持RFC 4492规范第5.1.1节中引用的所有SECG曲线(另请参见附录A)。在证书中,应使用未压缩的形式对点进行编码,并且应使用namedCurve选项对曲线进行编码,即使用对象标识符。
如果不满足这些要求,可能无法正确协商EC密码套件。
据推测,因为您的代码明确使用了" ECDSA" KeyPairGenerator
,原始密钥将" ECDSA" 作为算法公开,但在加载序列化表示时,BouncyCastle使用" EC& Oracle要求#34; 。
顺便说一句,如果您设置KEY_ALGORITHM = "EC"
,则会在两个输出中获得" EC" 。