Java常用的安全算法
安全算法主要包括 摘要算法、对称加密算法、非对称加密算法、信息编码以及数字签名、数字证书。
1.数字摘要
数字摘要也称为消息摘要,它是一个唯一对应一个消息或文本的固定长度的值,由一个单向Hash函数对消息进行计算而产生的。其生产过程如下图所示:
有如下特点:
(1)无论输入的消息有多长,计算出来的消息摘要的长度是固定的。应用MD5,计算出长度是128个比特位,使用SHA-1算法计算出来是160个比特位;
(2)只能进行正向的信息摘要,而无法从摘要中恢复出原来的消息。
常用的算法:
MD5及SHA算法。
java例子:
public class DigestTest { public static byte[] testMD5(String content) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] bytes = md.digest(content.getBytes("UTF-8")); return bytes; } public static byte[] testSHA1(String content) throws Exception { MessageDigest md = MessageDigest.getInstance("SHA1"); byte[] bytes = md.digest(content.getBytes("UTF-8")); return bytes; } public static void main(String args[]) throws Exception { String content = "123"; byte[] bytes = testMD5(content); String digest = DatatypeConverter.printHexBinary(bytes); System.out.println(digest); bytes = testSHA1(content); digest = DatatypeConverter.printHexBinary(bytes); System.out.println(digest); } }
2.对称加密算法
在对称加密算法中,数据发送方将明文和加密密钥经过特殊加密算法处理后,生成复杂的加密密文进行发送,数据接收方收到密文后,必须用相同的算法及密钥时行解密。其过程如下:
特点是算法公开、计算量小、加密速度快,加密效率高。
常用的加密算法包括:DES算法、3DES算法、AES算法。
Java例子:
AES对称算法加密:(用DES算法,只需要把AES改成DES即可)
public class AESTest { public static String genKeyAES() throws Exception { KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(128); SecretKey key = keyGenerator.generateKey(); String base64Key = DatatypeConverter.printBase64Binary(key.getEncoded()); return base64Key; } public static SecretKey loadKeyAES(String base64Key){ byte[] bytes = DatatypeConverter.parseBase64Binary(base64Key); SecretKey key = new SecretKeySpec(bytes, "AES"); return key; } public static byte[] encryptDES(byte[] source, SecretKey key) throws Exception { Cipher ciper = Cipher.getInstance("AES"); ciper.init(Cipher.ENCRYPT_MODE, key); byte[] bytes = ciper.doFinal(source); return bytes; } public static byte[] decrytDES(byte[] source, SecretKey key) throws Exception{ Cipher ciper = Cipher.getInstance("AES"); ciper.init(Cipher.DECRYPT_MODE, key); byte[] bytes = ciper.doFinal(source); return bytes; } public static void main(String args[]) throws Exception { String test = "1234"; String content = genKeyAES();//"12345678901234567890123456789012"; System.out.println(content); SecretKey secretKey = loadKeyAES(content); byte bytes[] = encryptDES(test.getBytes(), secretKey); System.out.println("secretKey String:" + DatatypeConverter.printHexBinary(bytes)); bytes = decrytDES (bytes, secretKey); System.out.println("decrytDES String:" + new String(bytes)); } }
3.非对称加密算法
又称为公开密钥加密算法,需要两个密钥,一个是公开密钥(public key),一个是私有密钥(private key),公钥和私钥需要配对使用。
基本过程:甲方生成一对密钥,并将其中的一把作为公钥向其他人公开,得到该公钥的乙方使用该密钥对机密信息进行加密后再发送给甲方,甲方再使用自己保存的另一把密钥(即私钥)对加密后的信息进行解密。如下图所示:
常用的算法:RSA算法
JAVA的例子:
public class RSATest { public static KeyPair getKeyPairt() throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(512); return keyPairGenerator.generateKeyPair(); } public static String getPublicKey(KeyPair keyPair){ PublicKey publicKey = keyPair.getPublic(); byte[] bytes = publicKey.getEncoded(); return DatatypeConverter.printBase64Binary(bytes); } public static String getPrivateKey(KeyPair keyPair){ PrivateKey privateKey = keyPair.getPrivate(); byte[] bytes = privateKey.getEncoded(); return DatatypeConverter.printBase64Binary(bytes); } public static PublicKey String2Publickey(String pubStr) throws Exception { byte[] bytes = DatatypeConverter.parseBase64Binary(pubStr); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } public static PrivateKey String2Privatekey(String privateStr) throws Exception { byte[] bytes = DatatypeConverter.parseBase64Binary(privateStr); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privatekey = keyFactory.generatePrivate(keySpec); return privatekey; } public static byte[] publicEncrypt(byte[] content, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(content); } public static byte[] privateEncrypt(byte[] content, PrivateKey privatekey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, privatekey); return cipher.doFinal(content); } public static byte[] publicDecrypt(byte[] content, PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(content); } public static byte[] privateDecrypt(byte[] content, PrivateKey privatekey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privatekey); return cipher.doFinal(content); } public static void main(String[] args) throws Exception { String str = "Hello, I am lai xiao hong"; byte[] bytes = str.getBytes(); KeyPair keyPair = getKeyPairt(); String publicKey = getPublicKey(keyPair); String privateKey = getPrivateKey(keyPair); System.out.println("publicKey:" + publicKey); System.out.println("privateKey:" + privateKey); //byte[] encBytes = publicEncrypt(bytes, String2Publickey(publicKey)); //byte[] decBytes = privateDecrypt(encBytes,String2Privatekey(privateKey)); byte[] encBytes = privateEncrypt(bytes, String2Privatekey(privateKey)); byte[] decBytes = publicDecrypt(encBytes, String2Publickey(publicKey)); System.out.println("Decrypt String:" + new String(decBytes)); } }
4.数字签名
签名认证是对非对称加密技术和数字摘要技术的综合运用,指的是将通信内容的商要信息使用发送者的私钥进行加密,然后将密文与原文一起传输给信息的接收者,接收者通过发送者的公钥解密被加密的摘要信息,然后使用与发送者相同的摘要算法,对接收的内容采用相同的方式产生摘要串,与解密的摘要串进行对比,如果相同,则说明接收到的内容是完整的,在传输过程中没有受到第五方篡改,否则说明通信内容已被第三方修改。
只有信息的发送者才能产生别人无法篡改的数字签名串,这个串能对信息发送者所发送的内容完整 性和发送者的身份进行校验和签别,通信正文经过相应的摘要算法生成摘要后,使用消息发送者的私钥进行加密,生成数字签名如下图所示:
消息的接收端收到信息的正文和对应的数字签名后,使用与发送端相同的摘要算法,生成通信正文的摘要,并且使用发送者的公钥对数字签名进行解密,得到发送商生成的摘要,进行比较后即可验证发送者的身份是否合法,正文内容是否被篡改,如下图所示:
常风的数字数字签名算法包括:MD%withRSA、SHA1withRSA等.
java 例子:
public class SignatureTest { private static byte[] sign(byte[] content, PrivateKey privateKey) throws Exception { Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(privateKey); signature.update(content); return signature.sign(); } private static boolean verify(byte[] content,byte[] sign, PublicKey publicKey) throws Exception{ Signature signature = Signature.getInstance("MD5withRSA"); signature.initVerify(publicKey); signature.update(content); return signature.verify(sign); } }
5.数字证书
也称为电子证书,通常包含如下内容:
- 对象的名称
- 证书的过期时间
- 颁发机构
- 签名算法
- 对象的公钥
大多数证书采用X.509的格式来保存证书,数字证书的签发过程实际上就是对数字证书的内容,包括证书所代表对象的公钥进行数字签名,而验证证书的过程,实际上是检验证书的数字签名。
在现实中,网络用户的数字证书需要数字认证机构(Certificate Authority,CA)来进行颁发,只有经过CA颁布的数字证书在网络中才具备认证性。
证书的生成过程如下:
证书的验证过程如下:
要获得数字证书,首先需要使用数字证书管理工具,如keytool,OpenSSL等,然后构建CSR(Certificate Signing Request)数字证书签发申请,提交给数字证书认证机构进行签名,最终形成数字证书。