由于计算机软件的非法复制,通信的泄密、数据安全受到威胁,解密及盗版问题日益严重,甚至引发国际争端,所以在信息安全技术中,加密技术占有不可替代的位置,因此对信息加密技术和加密手段的研究与开发,受到各国计算机界的重视,发展日新月异。现在就给大家介绍几种常用的加密算法。
1.密码中常用的术语
2.密码分类
3.OSI和TCP/IP安全体系
4.Java安全组成
5.Base64加密算法
6.消息摘要算法
6.1.消息摘要算法-MD家族
6.2.消息摘要算法-SHA家族
6.3.消息摘要算法-MAC家族
1.加密中常用的术语:
明文:待加密的信息
密文:加密后的明文
加密:明文转密文的过程
加密算法:明文转密文的转换算法
密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥。
加密密钥:通过加密算法进行加密过程中用的密钥
解密:将密文转名文的过程
解密算法:密文转明文的转换算法
解密密钥:通过解密算法进行解密过程中用的密钥
密码分析:截获密文这试图通过分析截获的密文从而推断出原来的明文或密钥的过程
主动攻击:攻击者非法入侵密码系统,采用伪造、修改、删除等手段向系统注入假消息进行欺骗(对密文有破坏作用)
被动攻击:对一个保密系统采取截获密文并对其进行分析和攻击(对密文没有破坏作用)
密码体系:由明文空间,密文空间,密钥空间,加密算法和解密算法五部分组成
密码协议:也称安全协议,指以密码学为基础的消息交换的通信协议,目的是在网络环境中提供安全的服务。
密码系统:用于加密和解密的系统
柯克霍夫原则:数据的安全基于密钥而不是算法的保密。即系统的安全取决于密钥,对密钥保密,对算法公开。-----现在密码学设计的基本原则
2.密码分类
- 按时间分:
- 古典密码:以字符为基本的加密单元
- 现代密码:以信息块为基本的加密单元
- 按保密内容分:
- 受限制算法:算法的保密基于保持算法的密码,常用语军事领域
- 基于密钥算法:算法的保密基于对密钥的保密
- 按密码体系分:
- 对称密码:别名单钥密码或私钥密码;指加密密钥和解密密钥相同
- 非对称密码:别名双钥密码或公钥密码;指加密密钥和解密密钥不同,密钥分为公钥和私钥
- 按明文的处理方法:
- 分组密码:指加密时将明文分成固定长度的组,用同一密钥和算法对每一组进行加密,输出也是固定长度的密文。多用于网络加密。
- 流密码:也称序列密码。指加密时每次加密一位或者一个字节明文。
3.OSI和TCP/IP安全体系
4.Java安全组成
Java 安全体系内核:它包括:字节码验证器、类加载器、安全管理器、访问控制器、访问权限管理器和策略描述工具等
Java代码在Java安全体系内核组件中的执行过程
- 字节码验证器分析字节码的顺序
- 字节码验证器检查对其它类的引用
例如,如果一个类要访问另一个类的方法,字节码验证器就要检查该方法是否为public.字节码验证器的典型操作包括:检查字节码的顺序是否以0XCAFEBABE开始,是否丢失字节,最后的类是否包含子类(它们不应该包括),方法的参数类型是什么等。如果一切正常,接下来类加载器将字节码翻译成java类,然后由java虚拟机(JVM)执行。如果需要加载一个特别的类可以定义不同的策略加以说明。通过委托给安全管理器的方式如果某个类可以访问特别的系统资源,那么类加载器和
java标准类也可以定义决策权。
- 安全管理器:是一个可有开发人员实现的特殊类,用于指明一个类是否可以访问指定的资源(例如,文件访问或网络连接)。为了做出决策,安全管理器需要分析请求来源。如果访问被拒绝,将会抛出一个java.lang.SecurityExceptin异常,否则的话,将会以通常的方式处理该调用。
JCA
- 它提供了Java平台上执行主要加密服务的基础设施,包括数字签名,信息摘要,密码,信息认证码密钥生成器和密钥生成器。同时JCA还保证了数据完整性并提供了显示全部特性的APIs。
- JCA仅仅是一个接口,可以有很多该接口的实现,它支持很大范围的标准算法包括RSA、DSA、三重DES、SHA、PKCS#5、RC2以及RC4.JCA是可扩展的,丰富的API可用于构建安全的应用,而其它还是算法与实现相互独立的,使用基于提供(可插拔)的体系结构。
其他体系结构
JCE
这是Sun微系统公司对数据块加密与解密的扩展,也是JCA实现的一部分。JCE是根据美国加密技术出口于第三方国家的条件对Java的扩展
JSSE
安全套接层(SSL)已经成为应用最为广泛的通过加密保证数据完整性的数据协议。JSSE是一个标准接口和对SSL协议的实现。开发人员可以使用另外一个商业化的SSL实现,而且通用JSSE接口仍旧可以使用。最新的Java平台包含了其它的安全套接协议,如传输层安全(TLS)、Kerberos和简单认证与安全层(SASL)。同时JSSE还包括SSL/TLS上的HTTPS支持。
JAAS
JAAS实现了基于用户认证的访问限制。和访问控制一起,它们提供了抽象的认证APIs函数,这些函数通过可插拔体系结构集成了各种登录机制。同时还提供了全面的策略与许可API,使用这些API允许开发人员创建和管理对安全敏感资源具有良好的访问控制的应用。 JAAS的一个重要特点是可以根据用户身份或代码签名实现多种认证机制单一登录服务和良好的资源访问控制。近来对于时间戳签名(始于Java5)的支持使得实施代码签名更加容易,避免了当签名证书过期时需要重签的麻烦。
java中安全服务都是从java.security.Provider类中的类似MessageDigestSpi 的子类提供的.XXXSpi是抽象父类
1)MessageDigest:对消息进行hash算法生成消息摘要(digest)。
2)Signature:对数据进行签名、验证数字签名。
3)KeyPairGenerator:根据指定的算法生成配对的公钥、私钥。
4)KeyFactory:根据Key说明(KeySpec)生成公钥或者私钥。
5)CertificateFactory:创建公钥证书和证书吊销列表(CRLs)。
6)KeyStore:keystore是一个keys的数据库。Keystore中的私钥会有一个相关联的证书链,证书用于鉴定对应的公钥。一个keystore也包含其它的信任的实体。
7)AlgorithmParameters:管理算法参数。KeyPairGenerator就是使用算法参数,进行算法相关的运算,生成KeyPair的。生成Signature时也会用到。
8)AlgorithmParametersGenerator:用于生成AlgorithmParameters。
9)SecureRandom:用于生成随机数或者伪随机数。
10)CertPathBuilder:用于构建证书链。
11)CertPathValidator:用于校验证书链。
12)CertStore:存储、获取证书链、CRLs到(从)CertStore中。
Provider 是jre1.5.0_16\lib\security文件中定义的:
security.provider.1=sun.security.provider.Sun
security.provider.2=sun.security.rsa.SunRsaSign
security.provider.3=com.sun.net.ssl.internal.ssl.Provider
security.provider.4=com.sun.crypto.provider.SunJCE
security.provider.5=sun.security.jgss.SunProvider
security.provider.6=com.sun.security.sasl.Provider
当然我们也可以实现自己的Provider,或者使用三方的,然后在该配置文件中配置一下即可。
Provider三方扩展
Base64加密算法
1.产生:邮件的“历史问题”
因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生
2.定义:Base64就是一种基于64个可打印字符来表示二进制数据的表示方法。
3.衍生:Base16、Base32、Url Base64
4.Base64代码实现
JDK实现
/**
* 使用JDK提供的api实现Base64
* @param src : 明文
*/
public static void jdkBase64(String src){
try {
//加密编码
BASE64Encoder encoder = new BASE64Encoder();
String encode = encoder.encode(src.getBytes());
System.out.println("jdk encoder:" + encode);
//解码
BASE64Decoder decoder = new BASE64Decoder();
String decode = new String(decoder.decodeBuffer(encode));
System.out.println("jdk decoder:" + decode);
} catch (IOException e) {
e.printStackTrace();
}
}
三方-Commons Codes实现
/**
* 使用三方-Commons Codes实现Base64
* @param src :明文
*/
public static void commonsCodesBase64(String src) {
//加密编码
byte[] encodeBytes = Base64.encodeBase64(src.getBytes());
System.out.println("cc encoder Base64:" + new String(encodeBytes));
//解码
byte[] decodeBytes = Base64.decodeBase64(encodeBytes);
System.out.println("cc decoder Base64:" + new String(decodeBytes));
}
三方-Bouncy Castle实现
/**
* 使用三方-Bouncy Castle实现Base64
* @param src :明文
*/
public static void bouncyCastleBase64(String src) {
//加密编码
byte[] encodeBytes = org.bouncycastle.util.encoders.Base64.encode(src.getBytes());
System.out.println("bc encoder Base64:" + new String(encodeBytes));
//解码
byte[] decodeBytes = org.bouncycastle.util.encoders.Base64.decode(encodeBytes);
System.out.println("bc decoder Base64:" + new String(decodeBytes));
}
总结
Base64:属于加密算法,是可逆的,经过encode后,可以将decode得到原文。在开发中,有的公司上传图片采用的是将图片转换成Base64字符串,再上传。在做加密相关的功能时,通常会将数据进行Base64加密/解密。其他的应用场景:邮件,证书等。
6.消息摘要算法
消息摘要(Message Digest)又称为数字摘要。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。因此消息摘要保证了消息的完整性,常用于验证数据的完整性。
6.1.消息摘要算法-MD家族
MD5:是一种不可逆的摘要算法,用于生成摘要,无法逆破解到原文,用于验证数据的有效性。比如,在网络请求接口中,通过将所有的参数生成摘要,客户端和服务端采用同样的规则生成摘要,这样可以防止篡改。又如,下载文件时,通过生成文件的摘要,用于验证文件是否损坏。
JDK实现
/**
* 使用JDK实现MD5加密
* @param src:消息
*/
public static void jdkMD5(String src) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5Bytes = md.digest(src.getBytes());
//转化为16进制字符串输出
System.out.println(Hex.encodeHexString(md5Bytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
如果想是想MD2等加密,只需要将MessageDigest.getInstance("MD2");参数换成对应的算法名称即可。
三方Bouncy Castle实现
/**
* 使用三方Bouncy Castle实现MD5加密
* @param src:消息
*/
public static void bouncyCastleMD5(String src) {
try {
Digest digest = new MD5Digest();
digest.update(src.getBytes(),0,src.getBytes().length);
byte[] md5Bytes = new byte[digest.getDigestSize()];
digest.doFinal(md5Bytes, 0);
//转化为16进制字符串输出
System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(md5Bytes));
} catch (Exception e) {
e.printStackTrace();
}
}
三方-Commons Codes实现
/**
* 使用三方Commons Codes实现MD5加密
* @param src:消息
*/
public static void commonsCodesMD5(String src) {
byte[] md5Bytes = DigestUtils.md5(src);
System.out.println(Hex.encodeHexString(md5Bytes));
}
MD应用
6.2.消息摘要算法-SHA家族
SHA算法分为一代和二代,这个是美国安全局发布的一系列的密码散列算法
除了SHA-1以外其他的也统称为SHA-2(二代)
JDK实现
/**
* 使用JDK实现SHA-1加密
* @param src
*/
public static void jdkSHA1(String src) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA");
digest.update(src.getBytes());
System.out.println(Hex.encodeHexString(digest.digest()));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
三方-Commons Codes实现
/**
* 使用三方Commons Codes实现SHA-1加密
* @param src:消息
*/
public static void commonsCodesSHA1(String src) {
String sha1Hex = DigestUtils.sha1Hex(src.getBytes());
System.out.println(sha1Hex);
}
三方-Bouncy Castle实现
/**
* 使用三方Bouncy Castle实现SHA-1加密
* @param src:消息
*/
public static void bouncyCastleSHA1(String src) {
Digest digest = new SHA1Digest();
digest.update(src.getBytes(), 0, src.getBytes().length);
byte[] sha1Bytes = new byte[digest.getDigestSize()];
digest.doFinal(sha1Bytes, 0);
System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(sha1Bytes));
}
应用
6.3.消息摘要算法-MAC家族
MAC(Message Authentication Code,消息认证码算法)是含有密钥散列函数算法,兼容了MD和SHA算法的特性,并在此基础上加上了密钥。因此MAC算法也经常被称作HMAC算法
使用JDK实现
/**
* 使用JDK实现HmacMD5(MAC)加密
* @param src
*/
public static void jdkHmacMD5(String src) {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");//初始化密钥生成器
SecretKey secretKey = keyGenerator.generateKey();//产生密钥
byte[] encoded = secretKey.getEncoded();//获取密钥
SecretKey restoreSecretKey = new SecretKeySpec(encoded, "HmacMD5");//还原密钥
Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());//实例化MAC
mac.init(restoreSecretKey);//初始化MAC
byte[] hmacmd5Bytes = mac.doFinal(src.getBytes());//执行摘要
System.out.println(Hex.encodeHexString(hmacmd5Bytes));
} catch (Exception e) {
e.printStackTrace();
}
}
使用Bouncy Castle实现
/**
* 使用三方Bouncy Castle实现MAC加密
* @param src:消息
*/
public static void bouncyCastleHmacMD5(String src) {
HMac hMac = new HMac(new MD5Digest());
hMac.init(new KeyParameter(org.bouncycastle.util.encoders.Hex.decode("gfdgfdgfdgfd")));
hMac.update(src.getBytes(),0,src.getBytes().length);
byte[] hmacmd5Bytes = new byte[hMac.getMacSize()];//执行摘要
hMac.doFinal(hmacmd5Bytes, 0);
System.out.println(org.bouncycastle.util.encoders.Hex.toHexString(hmacmd5Bytes));
}