Java加密与安全 (7)

  DSA(Digital Signature Algorithm),使用EIGamal数字签名算法,DSA只能配合SHA算法使用,所以有SHA1withDSA,SHA256withDSA,SHA512withDSA算法。和RSA数字签名算法相比,DSA算法更快。测试代码和测试RSA数字签名算法的代码一致,只需要修改算法名称就行了。

数字证书

数字正数:

非对称加密算法:对数据进行加密、解密

签名算法:确保数据的完整性和抗否认性

摘要算法:确保证书本身没有被篡改

  数字证书可以防止中间人攻击,因为它采用链式签名认证,即通过根证书(Root CA)去签名下一级证书,这样层层签名,直到最终的用户证书。而Root CA证书内置于操作系统中,所以,任何经过CA认证的数字证书都可以对其本身进行校验,确保证书本身不是伪造的。

import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.InputStream; import java.math.BigInteger; import java.security.*; import java.security.cert.X509Certificate; public class X509 { private final PrivateKey privateKey; public final X509Certificate certificate; // 证书和证书包含的公钥和摘要信息 public X509(KeyStore keyStore, String certName, String password) { try { this.privateKey = (PrivateKey) keyStore.getKey(certName,password.toCharArray()); this.certificate = (X509Certificate) keyStore.getCertificate(certName); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } //加密 public byte[] encrypt(byte[] message) { try { //获得加密算法 Cipher cipher = Cipher.getInstance(this.privateKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE,this.privateKey); return cipher.doFinal(message); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } //解密 public byte[] decrypt(byte[] message) { try { PublicKey publicKey = this.certificate.getPublicKey(); Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE,publicKey); return cipher.doFinal(message); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } public byte[] sign(byte[] message) { try { Signature signature = Signature.getInstance(this.certificate.getSigAlgName()); signature.initSign(this.privateKey); signature.update(message); return signature.sign(); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } public boolean verify(byte[] message, byte[] sign) { try { Signature signature = Signature.getInstance(this.certificate.getSigAlgName()); signature.initVerify(this.certificate); signature.update(message); return signature.verify(sign); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } //Java中的数字证书是存储在keyStore中的 public static KeyStore loadKeyStore(String keyStoreFile, String password) { try (InputStream input = new BufferedInputStream(new FileInputStream(keyStoreFile))) { if (input == null) { throw new RuntimeException("file not found in classpath: " + keyStoreFile); } KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(input, password.toCharArray()); return ks; } catch (Exception e) { throw new RuntimeException(e); } } public static void main(String[] args) throws Exception { byte[] message = "Hello, 使用X.509证书进行加密和签名!".getBytes("UTF-8"); // 读取KeyStore: KeyStore ks = loadKeyStore("my.keystore", "123456"); // 读取证书 X509 x509 = new X509(ks,"mycert", "123456"); // 加密: byte[] encrypted = x509.encrypt(message); System.out.println(String.format("encrypted: %x", new BigInteger(1, encrypted))); // 解密: byte[] decrypted = x509.decrypt(encrypted); System.out.println("decrypted: " + new String(decrypted, "UTF-8")); // 签名: byte[] sign = x509.sign(message); System.out.println(String.format("signature: %x", new BigInteger(1, sign))); // 验证签名: boolean verified = x509.verify(message, sign); System.out.println("verify: " + verified); } }

运行结果如下:

Java加密与安全

打开命令行,进入当前工程所在目录,输入命令:keytool -storepass 123456 -genkeypair -keyalg RSA -keysize 1024 -sigalg SHA1withRSA -validity 36500 -alias mycert -keystore my.keystore -dname "CN=www.sample.com, OU=sample, O=sample, L=BJ, ST=BJ, C=CN" 即可生成keystore文件,通过命令:keytool -list -keystore my.keystore -storepass 123456 可以看到keySore中的证书。
数字证书的应用:

https: HTTP over SSL

服务器发送证书给客户端(发送公钥/签名/CA)

客服端验证服务器证书(确认服务器身份)

客户端用证书加密随机口令并发送给服务器端(公钥加密)

服务器端解密获得口令(私钥解密)

双方随后使用AES加密进行通信(对称加密)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpypfg.html