Java加密算法
密码的常用术语:
1.密码体制:由明文空间、密文空间、密钥空间、加密算法和解密算法5部分组成。
2.密码协议:也称为安全协议,是指以密码学为基础的消息交换的通信协议,目的是在网络环境中提供安全的服务。
3.柯克霍夫原则:数据的安全基于密钥而不是算法的保密。即系统的安全取决于密钥,对密钥保密,对算法公开。——现代密码学设计的基本原则。
密码的分类:
按照时间可以分为古典密码和现代密码。
按照加密算法是否公开可以分为受限制的算法和基于密钥的算法(之所以把算法公开主要是防止加密算法的发明人利用它做一些不为人知的事)。
按照密码体制的不同可以分为对称密码、非对称密码。
按照明文的处理方法,可以分为:
- 分组密码:加密时将明文分成固定长度的组,用同一密钥和算法对每一块加密,输出也是固定长度的密文。多用于网络加密。
- 流密码:也称为序列密码。加密时每次加密一位或者一个字节明文。
散列函数(又称为hash函数),可以用来验证数据的完整性。它的特点是:长度不受限制、hash值容易计算、散列的运算是不可逆的。
与散列函数相关的算法有:消息摘要算法(MD5等)、安全散列算法(SHA)、消息认证码算法(MAC)。
数字签名:主要针对以数字的形式存储的消息进行的处理。
OSI与TCP/IP安全体系
业务流填充机制:在数据传输的过程中填入一些额外的信息混淆真实的数据。
Java安全组成、包、及第三方拓展
打开jdk安装目录下的jre\lib\security\java.security文件:
我们要使用第三地方的加解密的提供者可以在上面增加provider和它的引用。参看文档的上面一部分我们可以使用调用方法的形式,参见文档:
JDK本身提供了3个包:
java.security:消息摘要
javax.crypto:安全消息摘要,消息认证(鉴别)码
java.net.ssl:安全套接字(常用的类:HttpsURLConnection、SSLContext)
第三方java扩展:
Bouncy Castle:支持两种方案:①配置;②调用
Commons Codec:Apache,Base64、二进制、十六进制、字符集编码;URL编码/解码
Base64加密
base64算法是基于64个字符的一种替换算法。base64加密的产生式电子邮件的“历史问题”——邮件只能传输ASCII码。base64加密的应用场景:email、密钥、证书文件。该算法可以由3种方式实现:JDK、Bouncy Castle、Commons Codec。
实现如下:
1 package base64; 2 3 import java.io.IOException; 4 5 import org.apache.commons.codec.binary.Base64; 6 7 import sun.misc.BASE64Decoder; 8 import sun.misc.BASE64Encoder; 9 10 /** 11 * 该类是Base64算法的实现 12 */ 13 14 public class JavaBase64 { 15 16 private static String src = "面向对象编程,object-oriented!@#*5"; // 需要加密的原始字符串 17 18 public static void main(String[] args) throws IOException { 19 System.out.println("原始字符串:\t\t\t" + src); 20 System.out.println(); 21 jdkBase64(); 22 System.out.println(); 23 commonsCodecBase64(); 24 System.out.println(); 25 bouncyCastleBase64(); 26 } 27 28 /** JDK实现Base64编码 */ 29 public static void jdkBase64() throws IOException{ 30 //如果这里没有出现sun的base64可以从Build Path中删除然后添加 31 BASE64Encoder encoder = new BASE64Encoder(); 32 String encode = encoder.encode(src.getBytes());//编码 33 34 BASE64Decoder decoder = new BASE64Decoder(); 35 String decode = new String(decoder.decodeBuffer(encode));//解码 36 37 System.out.println("JDK实现的base64编码:\t\t" + encode); 38 System.out.println("JDK实现的base64解码:\t\t" + decode); 39 } 40 41 /** Commons Codec实现base64编码 */ 42 public static void commonsCodecBase64() { 43 byte[] encode = Base64.encodeBase64(src.getBytes()); 44 byte[] decode = Base64.decodeBase64(encode); 45 46 System.out.println("Commons Codec实现base64编码:\t" + new String(encode)); 47 System.out.println("Commons Codec实现base64解码:\t" + new String(decode)); 48 } 49 50 /**Bouncy Castle实现base64编码 */ 51 public static void bouncyCastleBase64() { 52 byte[] encode = org.bouncycastle.util.encoders.Base64.encode(src.getBytes()); 53 byte[] decode = org.bouncycastle.util.encoders.Base64.decode(encode); 54 55 System.out.println("Bouncy Castle实现base64编码:\t"+new String(encode)); 56 System.out.println("Bouncy Castle实现base64解码:\t"+new String(decode)); 57 } 58 }
运行结果:
消息摘要算法加密
消息摘要算法主要分为3类:MD(Message Digest)、SHA(Secure Hash Algorithm)、MAC(Message Authentication Code),以上3类算法的主要作用是验证数据的完整性——是数字签名的核心算法。
消息摘要算法——MD
MD算法家族有3类MD2、MD4、MD5,MD家族生成的都是128位的信息摘要。
算法 | 摘要长度 | 实现方 |
MD2 | 128 | JDK |
MD4 | 128 | Bouncy Castle |
MD5 | 128 | JDK |
信息摘要算法由于使用的是一种单向函数,所以理论上是不可破解的(山东大学的王晓云教授已经破解了MD5和SHA,所以消息摘要是可以伪造的,只不过难度比较大)。所有MD算法进行摘要的结果都是128为位(32位16进制的数字,因为1位16进制数代表4位二进制数)。
以下是Java中实现的各种MD加密:
1 package md; 2 3 import java.security.MessageDigest; 4 import java.security.NoSuchAlgorithmException; 5 import java.security.Security; 6 7 import org.apache.commons.codec.binary.Hex; 8 import org.apache.commons.codec.digest.DigestUtils; 9 import org.bouncycastle.crypto.Digest; 10 import org.bouncycastle.crypto.digests.MD2Digest; 11 import org.bouncycastle.crypto.digests.MD5Digest; 12 import org.bouncycastle.jce.provider.BouncyCastleProvider; 13 14 public class JavaMD { 15 16 private static String src = "object-oriented"; // 需要加密的原始字符串 17 18 public static void main(String[] args) throws NoSuchAlgorithmException { 19 System.out.println("原始字符串:" + src + "\n"); 20 21 jdkMD5(); 22 bouncyCastleMD5(); 23 commonsCodecMD5(); 24 System.out.println(); 25 26 jdkMD2(); 27 bouncyCastleMD2(); 28 commonsCodecMD2(); 29 System.out.println(); 30 31 bouncyCastleMD4(); 32 } 33 34 /** jdk实现MD5加密 */ 35 public static void jdkMD5() throws NoSuchAlgorithmException { 36 37 MessageDigest md = MessageDigest.getInstance("MD5"); 38 byte[] md5Bytes = md.digest(src.getBytes()); 39 System.out.println("JDK MD5:" + Hex.encodeHexString(md5Bytes));//利用第三方包将byte数组转化为16进制字符串 40 } 41 42 /** jdk实现MD2加密 */ 43 public static void jdkMD2() throws NoSuchAlgorithmException { 44 45 MessageDigest md = MessageDigest.getInstance("md2"); 46 byte[] md5Bytes = md.digest(src.getBytes()); 47 System.out.println("JDK MD2:" + Hex.encodeHexString(md5Bytes)); 48 } 49 50 /** Bouncy Castle实现MD4加密 */ 51 public static void bouncyCastleMD4() throws NoSuchAlgorithmException{ 52 /*通过这种方式给JDK动态添加一个provider,就可以通过这种方式获得JDK本身不支持的MD4了*/ 53 Security.addProvider(new BouncyCastleProvider()); 54 55 MessageDigest md = MessageDigest.getInstance("md4"); 56 57 byte[] md4Bytes = md.digest(src.getBytes()); 58 System.out.println("bc MD4:\t" + org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes)); 59 } 60 61 /** Bouncy Castle实现MD5加密 */ 62 public static void bouncyCastleMD5(){ 63 Digest digest = new MD5Digest(); 64 digest.update(src.getBytes(), 0, src.getBytes().length); 65 byte[]md5Bytes = new byte[digest.getDigestSize()]; 66 digest.doFinal(md5Bytes, 0); 67 System.out.println("bc MD5:\t" + org.bouncycastle.util.encoders.Hex.toHexString(md5Bytes)); 68 } 69 70 /** Bouncy Castle实现MD2加密 */ 71 public static void bouncyCastleMD2(){ 72 Digest digest = new MD2Digest(); 73 digest.update(src.getBytes(), 0, src.getBytes().length); 74 byte[]md2Bytes = new byte[digest.getDigestSize()]; 75 digest.doFinal(md2Bytes, 0); 76 System.out.println("bc MD2:\t" + org.bouncycastle.util.encoders.Hex.toHexString(md2Bytes)); 77 78 } 79 80 /** Commons Codec 实现MD5加密*/ 81 public static void commonsCodecMD5() { 82 System.out.println("cc MD5:\t" + DigestUtils.md5Hex(src.getBytes())); 83 } 84 85 /** Commons Codec 实现MD2加密*/ 86 public static void commonsCodecMD2() { 87 System.out.println("cc MD2:\t" + DigestUtils.md2Hex(src.getBytes())); 88 } 89 }
以上程序的运行结果:
JDK本身提供了MD2和MD5的实现,apache的Commons Codec在JDK的基础上进行了改良,使用Commons Codec提供接口进行MD2和MD5加密将会简单很多。JDK本省并没有提供MD4算法的实现,但是我们可以通过动态添加provider的方式让jdk支持MD4,见以下代码:
1 /* 通过这种方式给JDK动态添加一个provider,就可以通过这种方式获得JDK本身不支持的MD4了 */ 2 Security.addProvider(new BouncyCastleProvider()); 3 4 MessageDigest md = MessageDigest.getInstance("md4"); 5 6 byte[] md4Bytes = md.digest(src.getBytes()); 7 System.out.println("bc MD4:\t" + org.bouncycastle.util.encoders.Hex.toHexString(md4Bytes));
Bouncy Castle提供了MD2、MD4和MD5的实现,对消息摘要算法的支持比较完善,但是API还是没有Apache的Commons Codec友善。因此,如果我们要进行MD2和MD4实现,最好选用Commons Codec。
MD算法的应用
注册时:
应用程序服务器将用户提交的密码进行MD5即:数据库中存放的用户名是明文,而密码是密文(16进制字符串)摘要算法,得到32位的16进制字符串(密文)。把用户名(明文)和密码(密文)进行信息持久化存储到数据库中,返回注册结果。
登录时:
应用程序服务器同样对密码进行MD5摘要,然后将用户提交的用户名和密码的摘要信息和数据库中存储的信息进行比对,返回登录结果。
消息摘要算法——SHA
安全散列算法,固定长度的摘要信息。被认为是MD5的继承者。是一个系列,包括SHA-1、SHA-2(SHA-224、SHA-256、SHA-384、SHA-512),也就是除了SHA-1,其他的4种都被称为是SHA-2。每种算法的摘要长度和实现方如下:
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。