一、
下午在编写ECDH算法中乙方用甲方公钥产生密钥时,想到keyFactory能把密钥材料变成密钥,我是这么敲的:
public static final Map<String,Object> initKey(byte[] key) throws NoSuchAlgorithmException, InvalidKeySpecException{
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
ECPublicKey pubKey = (ECPublicKey)keyFactory.generatePublic(x509EncodedKeySpec);
ECParameterSpec ecParam = pubKey.getParams();
ECPublicKey publicKey = (ECPublicKey) keyFactory.generatePublic((KeySpec) ecParam);
ECPrivateKey privateKey = (ECPrivateKey)keyFactory.generatePrivate((KeySpec)ecParam);
Map<String,Object> keyMap = new HashMap<String,Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
Junit报错:java.lang.ClassCastException: sun.security.ec.NamedCurve cannot be cast to java.security.spec.KeySpec
at com.fdc.ECDHCoder.initKey(ECDHCoder.java:63)
at com.fdc.ECDHCoderTest.initKey(ECDHCoderTest.java:36)
……
通过查证发现,ECParameterSpec对象并非KeySpec的子类,它们的关系是这样的:
interface | AlgorithmParamSpec |
class | ECParamterSpec |
ECParamterSpec实现了AlgorithmParamSpec接口
而KeyPairGenerator能接收这个参数
Class KeyPairGenerator
- java.lang.Object
-
- java.security.KeyPairGeneratorSpi
-
- java.security.KeyPairGenerator
void | initialize(AlgorithmParameterSpec params)
Initializes the key pair generator using the specified parameter set and the
SecureRandom implementation of the highest-priority installed provider as the source of randomness.
|
void | initialize(AlgorithmParameterSpec params, SecureRandom random)
Initializes the key pair generator with the given parameter set and source of randomness.
|
void | initialize(int keysize)
Initializes the key pair generator for a certain keysize using a default parameter set and the
SecureRandom implementation of the highest-priority installed provider as the source of randomness.
|
void | initialize(int keysize, SecureRandom random)
Initializes the key pair generator for a certain keysize with the given source of randomness (and a default parameter set).
|
进一步查询得到:
Interface KeySpec
-
-
All Known Implementing Classes:
- DESedeKeySpec, DESKeySpec, DHPrivateKeySpec, DHPublicKeySpec, DSAPrivateKeySpec, DSAPublicKeySpec, ECPrivateKeySpec, ECPublicKeySpec, EncodedKeySpec, PBEKeySpec, PKCS8EncodedKeySpec, RSAMultiPrimePrivateCrtKeySpec, RSAPrivateCrtKeySpec, RSAPrivateKeySpec, RSAPublicKeySpec, SecretKeySpec, X509EncodedKeySpec
Class KeyFactory
- java.lang.Object
-
- java.security.KeyFactory
Modifier and Type | Method and Description |
---|---|
PrivateKey | generatePrivate(KeySpec keySpec)
Generates a private key object from the provided key specification (key material).
|
PublicKey | generatePublic(KeySpec keySpec) |
而且并没有产生SecretKey的方法,回到AES算法发现,原来当时的secretKey是由SecretKeyFactory产生的
Class SecretKeyFactory
- java.lang.Object
-
- javax.crypto.SecretKeyFactory
Modifier and Type | Method and Description |
---|---|
SecretKey | generateSecret(KeySpec keySpec)
Generates a
SecretKey object from the provided key specification (key material).
|
不但如此,SecretKeyFactory并不继承KeyFactory,两者是并列的!
综上,
KeyFactory的作用细化为:可将密钥材料类KeySpec对象转换成PublicKey,PrivateKey类对象
Interface PublicKey
-
-
All Superinterfaces:
- Key, Serializable
-
All Known Subinterfaces:
- DHPublicKey, DSAPublicKey, ECPublicKey, RSAPublicKey
http://www.bouncycastle.org/latest_releases.html
注意JDK,JRE目录下java,security的替换
三、小结:
1.DH算法的精髓:甲乙双方并没有交换本地密钥,依然可以完成数据对称加密的实现!
2.ECDH算法密钥长度取值:112,256,571,对本地密钥的算法不如DH那样全面,AES,DES,DESede都失败
3.X509EncodedKeySpec 和 PKCS8KeySpec 为EncodedKeySpec的子类,前者用于转换公钥编码密钥,后者用于转换私钥编码密钥