Java密码学 - 4. 非对称密钥

  1. 非对称加密 asymmetric cryptography
  2. 代码实现
  3. 获取密钥
  4. 延申

非对称加密 asymmetric cryptography

公钥+原文+算法=密文

私钥+密文+算法=原文

Image result for asymmetric cryptography

代码实现

生成非对称密钥

1
2
3
4
5
6
//java.security.KeyPairGenerator
KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");
keyGen.initialize(keylength);//长度
KeyPair pair =keyGen.generateKeyPair();//生成密钥对
pair.getPrivate();
pair.getPublic();

获取密钥

公钥私钥的格式一般是PKCS#8,除非特别要求PKCS#1。

常见(1)从文件读取密钥(PKCS#8)

1
2
3
4
5
6
7
//apache IO的功能,直接获取byte[]
byte[] bytes =FileUtils.readFileToByteArray(new File(filename));
//RSA具有随机性, 所以无法做到基于password的公钥私钥
//这里只是从已经是成品的公钥,私钥文件里提取出来,再转换成程序可以处理的privatekey和publickey
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);

常见(2)从文件读取pem格式的密钥(PKCS#8) 参考Java密码学 - 5. pem格式的读写

1
2
3
4
5
PEMParser pp = new PEMParser(new FileReader("project/test/public2.pem"));
PEMKeyPair pemKeyPair = (PEMKeyPair) pp.readObject();
KeyPair kp = new JcaPEMKeyConverter().getKeyPair(pemKeyPair);
pair.getPrivate();
pair.getPublic();

延申

(1)私钥转换格式至PKCS#1

1
2
3
4
5
PrivateKey prik=...
PrivateKeyInfo pkInfo = PrivateKeyInfo.getInstance(prik.getEncoded());
ASN1Encodable encodable = pkInfo.parsePrivateKey();
ASN1Primitive primitive = encodable.toASN1Primitive();
byte[] privateKeyPKCS1 = primitive.getEncoded();

(2)获得证书(publickey)

1
2
3
4
5
6
7
// X509Certificate x509Certificate = getX509Certificate("keypair/cxj1.cer");
// x509Certificate.getPublicKey();
X509Certificate getX509Certificate(String certfile) throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("x509");
        return (X509Certificate) cf.generateCertificate(FileUtils.openInputStream(
		        new File(certfile)));
}

(3)从密钥管理器获取证书(privatekey)

1
2
3
4
5
6
7
8
9
//获得keystore
KeyStore ks=...
//密钥的名称,keystore的密码
//获得private key
PrivateKey prik= (PrivateKey) ks.getKey(alias, password.toCharArray());
//获得密钥名称
//获得证书|public key
X509Certificate certificate = (X509Certificate) ks.gkeyStore.getCertificate(alias)
//获得public操作, 如上面所说