- 浏览: 66782 次
文章分类
最新评论
-
小灯笼:
ZooKeeper分布式专题与Dubbo微服务入门网盘地址:h ...
dubbo+zookeeper构建高可用分布式集群 -
qingfengxiu1985:
有没有全部工程代码?发一个呗,邮箱:qingfengxiu19 ...
mongodb+spring +morphia完整版框架搭建
1 密码学简介
2.1 概念
(1) 发送者和接收者
假设发送者想发送消息给接收者,且想安全地发送信息:她想确信偷听者不能阅读发送的消息。
(2) 消息和加密
消息被称为明文。用某种方法伪装消息以隐藏它的内容的过程称为加密,加了密的消息称为密文,而把密文转变为明文的过程称为解密。
明文用M(消息)或P(明文)表示,它可能是比特流(文本文件、位图、数字化的语音流或数字化的视频图像)。至于涉及到计算机,P是简单的二进制数据。明文可被传送或存储,无论在哪种情况,M指待加密的消息。
密文用C表示,它也是二进制数据,有时和M一样大,有时稍大(通过压缩和加密的结合,C有可能比P小些。然而,单单加密通常达不到这一点)。加密函数E作用于M得到密文C,用数学表示为:
E(M)=C.
相反地,解密函数D作用于C产生M
D(C)=M.
先加密后再解密消息,原始的明文将恢复出来,下面的等式必须成立:
D(E(M))=M
(3) 鉴别、完整性和抗抵赖
除了提供机密性外,密码学通常有其它的作用:.
(a) 鉴别
消息的接收者应该能够确认消息的来源;入侵者不可能伪装成他人。
(b) 完整性检验
消息的接收者应该能够验证在传送过程中消息没有被修改;入侵者不可能用假消息代替合法消息。
(c) 抗抵赖
发送者事后不可能虚假地否认他发送的消息。
(4) 算法和密钥
密码算法也叫密码,是用于加密和解密的数学函数。(通常情况下,有两个相关的函数:一个用作加密,另一个用作解密)
如果算法的保密性是基于保持算法的秘密,这种算法称为受限制的算法。受限制的算法具有历史意义,但按现在的标准,它们的保密性已远远不够。大的或经常变换的用户组织不能使用它们,因为每有一个用户离开这个组织,其它的用户就必须改换另外不同的算法。如果有人无意暴露了这个秘密,所有人都必须改变他们的算法。
更糟的是,受限制的密码算法不可能进行质量控制或标准化。每个用户组织必须有他们自己的唯一算法。这样的组织不可能采用流行的硬件或软件产品。但偷听者却可以买到这些流行产品并学习算法,于是用户不得不自己编写算法并予以实现,如果这个组织中没有好的密码学家,那么他们就无法知道他们是否拥有安全的算法。
尽管有这些主要缺陷,受限制的算法对低密级的应用来说还是很流行的,用户或者没有认识到或者不在乎他们系统中内在的问题。
现代密码学用密钥解决了这个问题,密钥用K表示。K可以是很多数值里的任意值。密钥K的可能值的范围叫做密钥空间。加密和解密运算都使用这个密钥(即运算都依赖于密钥,并用K作为下标表示),这样,加/解密函数现在变成:
EK(M)=C
DK(C)=M.
这些函数具有下面的特性:
DK(EK(M))=M.
有些算法使用不同的加密密钥和解密密钥,也就是说加密密钥K1与相应的解密密钥K2不同,在这种情况下:
EK1(M)=C
DK2(C)=M
DK2 (EK1(M))=M
所有这些算法的安全性都基于密钥的安全性;而不是基于算法的细节的安全性。这就意味着算法可以公开,也可以被分析,可以大量生产使用算法的产品,即使偷听者知道你的算法也没有关系;如果他不知道你使用的具体密钥,他就不可能阅读你的消息。
密码系统由算法、以及所有可能的明文、密文和密钥组成的。
基于密钥的算法通常有两类:对称算法和公开密钥算法。下面将分别介绍:
2.2 对称密码算法
对称算法有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,反过来也成立。在大多数对称算法中,加/解密密钥是相同的。这些算法也叫秘密密钥算法或单密钥算法,它要求发送者和接收者在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都能对消息进行加/解密。只要通信需要保密,密钥就必须保密。
对称算法的加密和解密表示为:
EK(M)=C
DK(C)=M
对称算法可分为两类。一次只对明文中的单个比特(有时对字节)运算的算法称为序列算法或序列密码。另一类算法是对明文的一组比特亚行运算,这些比特组称为分组,相应的算法称为分组算法或分组密码。现代计算机密码算法的典型分组长度为64比特——这个长度大到足以防止分析破译,但又小到足以方便使用(在计算机出现前,算法普遍地每次只对明文的一个字符运算,可认为是序列密码对字符序列的运算)。
2.3 公开密码算法
公开密钥算法(也叫非对称算法)是这样设计的:用作加密的密钥不同于用作解密的密钥,而且解密密钥不能根据加密密钥计算出来(至少在合理假定的长时间内)。之所以叫做公开密钥算法,是因为加密密钥能够公开,即陌生者能用加密密钥加密信息,但只有用相应的解密密钥才能解密信息。在这些系统中,加密密钥叫做公开密钥(简称公钥),解密密钥叫做私人密钥(简称私钥)。私人密钥有时也叫秘密密钥。为了避免与对称算法混淆,此处不用秘密密钥这个名字。
用公开密钥K加密表示为
EK(M)=C.
虽然公开密钥和私人密钥是不同的,但用相应的私人密钥解密可表示为:
DK(C)=M
有时消息用私人密钥加密而用公开密钥解密,这用于数字签名(后面将详细介绍),尽管可能产生混淆,但这些运算可分别表示为:
EK(M)=C
DK(C)=M
当前的公开密码算法的速度,比起对称密码算法,要慢的多,这使得公开密码算法在大数据量的加密中应用有限。
2.4 单向散列函数
单向散列函数 H(M) 作用于一个任意长度的消息 M,它返回一个固定长度的散列值 h,其中 h 的长度为 m 。
输入为任意长度且输出为固定长度的函数有很多种,但单向散列函数还有使其单向的其它特性:
(1) 给定 M ,很容易计算 h ;
(2) 给定 h ,根据 H(M) = h 计算 M 很难 ;
(3) 给定 M ,要找到另一个消息 M‘ 并满足 H(M) = H(M’) 很难。
在许多应用中,仅有单向性是不够的,还需要称之为“抗碰撞”的条件:
要找出两个随机的消息 M 和 M‘,使 H(M) = H(M’) 满足很难。
由于散列函数的这些特性,由于公开密码算法的计算速度往往很慢,所以,在一些密码协议中,它可以作为一个消息 M 的摘要,代替原始消息 M,让发送者为 H(M) 签名而不是对 M 签名 。
如 SHA 散列算法用于数字签名协议 DSA中。
2.5 数字签名
提到数字签名就离不开公开密码系统和散列技术。
有几种公钥算法能用作数字签名。在一些算法中,例如RSA,公钥或者私钥都可用作加密。用你的私钥加密文件,你就拥有安全的数字签名。在其它情况下,如DSA,算法便区分开来了??数字签名算法不能用于加密。这种思想首先由Diffie和Hellman提出 。
基本协议是简单的 :
(1) A 用她的私钥对文件加密,从而对文件签名。
(2) A 将签名的文件传给B。
(3) B用A的公钥解密文件,从而验证签名。
这个协议中,只需要证明A的公钥的确是她的。如果B不能完成第(3)步,那么他知道签名是无效的。
这个协议也满足以下特征:
(1) 签名是可信的。当B用A的公钥验证信息时,他知道是由A签名的。
(2) 签名是不可伪造的。只有A知道她的私钥。
(3) 签名是不可重用的。签名是文件的函数,并且不可能转换成另外的文件。
(4) 被签名的文件是不可改变的。如果文件有任何改变,文件就不可能用A的公钥验证。
(5) 签名是不可抵赖的。B不用A的帮助就能验证A的签名。
在实际应用中,因为公共密码算法的速度太慢,签名者往往是对消息的散列签名而不是对消息本身签名。这样做并不会降低签名的可信性。
MD5、SHA、HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠 但是可以通过自定义去改变:
自定义MD5加密算法
SHA
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了, 但是SHA仍然是公认的安全加密算法,较之MD5更为安全
HMAC
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。
BASE64的加密解密是双向的,可以求反解。
MD5、SHA以及HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。其中HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。
单向加密的用途主要是为了校验数据在传输过程中是否被修改。
http://security.group.iteye.com/group/wiki/1710-one-way-encryption-algorithm
对称加密和非对称加密 : 对称加密加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。非对称加密使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。
对称加密:
DES加密算法:
AES对称加密算法,高级加密
RSA非对称加密算法
加密分组算法模式:
ECB(Electronic Code Book电子密码本)模式
ECB模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。
优点: 1.简单; 2.有利于并行计算; 3.误差不会被扩散;
缺点: 1.不能隐藏明文的模式; 2.可能对明文进行主动攻击;
因此,此模式适于加密小消息。
CBC(Cipher Block Chaining,加密块链)模式
优点: 不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
缺点: 1.不利于并行计算; 2.误差传递; 3.需要初始化向量IV
CFB(Cipher FeedBack Mode,加密反馈)模式
优点:
1.隐藏了明文模式; 2.分组密码转化为流模式; 3.可以及时加密传送小于分组的数据;
缺点: 1.不利于并行计算; 2.误差传送:一个明文单元损坏影响多个单元; 3.唯一的IV;
OFB(Output FeedBack,输出反馈)模式
优点: 1.隐藏了明文模式; 2.分组密码转化为流模式; 3.可以及时加密传送小于分组的数据;
缺点: 1.不利于并行计算; 2.对明文的主动攻击是可能的; 3.误差传送:一个明文单元损坏影响多个单元;
找了一些资料,做一写demo,还没有完全掌握密码学。 学习笔记先做在这里。
2.1 概念
(1) 发送者和接收者
假设发送者想发送消息给接收者,且想安全地发送信息:她想确信偷听者不能阅读发送的消息。
(2) 消息和加密
消息被称为明文。用某种方法伪装消息以隐藏它的内容的过程称为加密,加了密的消息称为密文,而把密文转变为明文的过程称为解密。
明文用M(消息)或P(明文)表示,它可能是比特流(文本文件、位图、数字化的语音流或数字化的视频图像)。至于涉及到计算机,P是简单的二进制数据。明文可被传送或存储,无论在哪种情况,M指待加密的消息。
密文用C表示,它也是二进制数据,有时和M一样大,有时稍大(通过压缩和加密的结合,C有可能比P小些。然而,单单加密通常达不到这一点)。加密函数E作用于M得到密文C,用数学表示为:
E(M)=C.
相反地,解密函数D作用于C产生M
D(C)=M.
先加密后再解密消息,原始的明文将恢复出来,下面的等式必须成立:
D(E(M))=M
(3) 鉴别、完整性和抗抵赖
除了提供机密性外,密码学通常有其它的作用:.
(a) 鉴别
消息的接收者应该能够确认消息的来源;入侵者不可能伪装成他人。
(b) 完整性检验
消息的接收者应该能够验证在传送过程中消息没有被修改;入侵者不可能用假消息代替合法消息。
(c) 抗抵赖
发送者事后不可能虚假地否认他发送的消息。
(4) 算法和密钥
密码算法也叫密码,是用于加密和解密的数学函数。(通常情况下,有两个相关的函数:一个用作加密,另一个用作解密)
如果算法的保密性是基于保持算法的秘密,这种算法称为受限制的算法。受限制的算法具有历史意义,但按现在的标准,它们的保密性已远远不够。大的或经常变换的用户组织不能使用它们,因为每有一个用户离开这个组织,其它的用户就必须改换另外不同的算法。如果有人无意暴露了这个秘密,所有人都必须改变他们的算法。
更糟的是,受限制的密码算法不可能进行质量控制或标准化。每个用户组织必须有他们自己的唯一算法。这样的组织不可能采用流行的硬件或软件产品。但偷听者却可以买到这些流行产品并学习算法,于是用户不得不自己编写算法并予以实现,如果这个组织中没有好的密码学家,那么他们就无法知道他们是否拥有安全的算法。
尽管有这些主要缺陷,受限制的算法对低密级的应用来说还是很流行的,用户或者没有认识到或者不在乎他们系统中内在的问题。
现代密码学用密钥解决了这个问题,密钥用K表示。K可以是很多数值里的任意值。密钥K的可能值的范围叫做密钥空间。加密和解密运算都使用这个密钥(即运算都依赖于密钥,并用K作为下标表示),这样,加/解密函数现在变成:
EK(M)=C
DK(C)=M.
这些函数具有下面的特性:
DK(EK(M))=M.
有些算法使用不同的加密密钥和解密密钥,也就是说加密密钥K1与相应的解密密钥K2不同,在这种情况下:
EK1(M)=C
DK2(C)=M
DK2 (EK1(M))=M
所有这些算法的安全性都基于密钥的安全性;而不是基于算法的细节的安全性。这就意味着算法可以公开,也可以被分析,可以大量生产使用算法的产品,即使偷听者知道你的算法也没有关系;如果他不知道你使用的具体密钥,他就不可能阅读你的消息。
密码系统由算法、以及所有可能的明文、密文和密钥组成的。
基于密钥的算法通常有两类:对称算法和公开密钥算法。下面将分别介绍:
2.2 对称密码算法
对称算法有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,反过来也成立。在大多数对称算法中,加/解密密钥是相同的。这些算法也叫秘密密钥算法或单密钥算法,它要求发送者和接收者在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都能对消息进行加/解密。只要通信需要保密,密钥就必须保密。
对称算法的加密和解密表示为:
EK(M)=C
DK(C)=M
对称算法可分为两类。一次只对明文中的单个比特(有时对字节)运算的算法称为序列算法或序列密码。另一类算法是对明文的一组比特亚行运算,这些比特组称为分组,相应的算法称为分组算法或分组密码。现代计算机密码算法的典型分组长度为64比特——这个长度大到足以防止分析破译,但又小到足以方便使用(在计算机出现前,算法普遍地每次只对明文的一个字符运算,可认为是序列密码对字符序列的运算)。
2.3 公开密码算法
公开密钥算法(也叫非对称算法)是这样设计的:用作加密的密钥不同于用作解密的密钥,而且解密密钥不能根据加密密钥计算出来(至少在合理假定的长时间内)。之所以叫做公开密钥算法,是因为加密密钥能够公开,即陌生者能用加密密钥加密信息,但只有用相应的解密密钥才能解密信息。在这些系统中,加密密钥叫做公开密钥(简称公钥),解密密钥叫做私人密钥(简称私钥)。私人密钥有时也叫秘密密钥。为了避免与对称算法混淆,此处不用秘密密钥这个名字。
用公开密钥K加密表示为
EK(M)=C.
虽然公开密钥和私人密钥是不同的,但用相应的私人密钥解密可表示为:
DK(C)=M
有时消息用私人密钥加密而用公开密钥解密,这用于数字签名(后面将详细介绍),尽管可能产生混淆,但这些运算可分别表示为:
EK(M)=C
DK(C)=M
当前的公开密码算法的速度,比起对称密码算法,要慢的多,这使得公开密码算法在大数据量的加密中应用有限。
2.4 单向散列函数
单向散列函数 H(M) 作用于一个任意长度的消息 M,它返回一个固定长度的散列值 h,其中 h 的长度为 m 。
输入为任意长度且输出为固定长度的函数有很多种,但单向散列函数还有使其单向的其它特性:
(1) 给定 M ,很容易计算 h ;
(2) 给定 h ,根据 H(M) = h 计算 M 很难 ;
(3) 给定 M ,要找到另一个消息 M‘ 并满足 H(M) = H(M’) 很难。
在许多应用中,仅有单向性是不够的,还需要称之为“抗碰撞”的条件:
要找出两个随机的消息 M 和 M‘,使 H(M) = H(M’) 满足很难。
由于散列函数的这些特性,由于公开密码算法的计算速度往往很慢,所以,在一些密码协议中,它可以作为一个消息 M 的摘要,代替原始消息 M,让发送者为 H(M) 签名而不是对 M 签名 。
如 SHA 散列算法用于数字签名协议 DSA中。
2.5 数字签名
提到数字签名就离不开公开密码系统和散列技术。
有几种公钥算法能用作数字签名。在一些算法中,例如RSA,公钥或者私钥都可用作加密。用你的私钥加密文件,你就拥有安全的数字签名。在其它情况下,如DSA,算法便区分开来了??数字签名算法不能用于加密。这种思想首先由Diffie和Hellman提出 。
基本协议是简单的 :
(1) A 用她的私钥对文件加密,从而对文件签名。
(2) A 将签名的文件传给B。
(3) B用A的公钥解密文件,从而验证签名。
这个协议中,只需要证明A的公钥的确是她的。如果B不能完成第(3)步,那么他知道签名是无效的。
这个协议也满足以下特征:
(1) 签名是可信的。当B用A的公钥验证信息时,他知道是由A签名的。
(2) 签名是不可伪造的。只有A知道她的私钥。
(3) 签名是不可重用的。签名是文件的函数,并且不可能转换成另外的文件。
(4) 被签名的文件是不可改变的。如果文件有任何改变,文件就不可能用A的公钥验证。
(5) 签名是不可抵赖的。B不用A的帮助就能验证A的签名。
在实际应用中,因为公共密码算法的速度太慢,签名者往往是对消息的散列签名而不是对消息本身签名。这样做并不会降低签名的可信性。
MD5、SHA、HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠 但是可以通过自定义去改变:
自定义MD5加密算法
package demo.dcn.service.utils.security; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Md5Util { // 全局数组 private final static String[] strDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f","h","g","i","j","k","m","n","o", "p","q","x","y","z","u","w","=","+","-","^","*","#","v"}; public Md5Util() { } /** * 返回形式为数字跟字符串 * @param bByte * @return */ private static String byteToArrayString(byte bByte) { int iRet = bByte; // System.out.println("iRet="+iRet); if (iRet < 0) { iRet += 256; } int iD1 = iRet / 38; int iD2 = iRet % 38; return strDigits[iD1] + strDigits[iD2]; } /** * 转换字节数组为16进制字串 * @param bByte * @return */ private static String byteToString(byte[] bByte) { StringBuffer sBuffer = new StringBuffer(); for (int i = 0; i < bByte.length; i++) { sBuffer.append(byteToArrayString(bByte[i])); } return sBuffer.toString(); } /** * HASH加密 * @param strObj * @return */ public static String GetMD5Code(String strObj) { String resultString = null; try { resultString = new String(strObj); MessageDigest md = MessageDigest.getInstance("MD5"); // md.digest() 该函数返回值为存放哈希值结果的byte数组 resultString = byteToString(md.digest(strObj.getBytes())); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } return resultString; } public static void main(String[] args) { Md5Util getMD5 = new Md5Util(); System.out.println(getMD5.GetMD5Code("012365498kdask")); System.out.println(getMD5.GetMD5Code("0123654abc")); } }
SHA
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了, 但是SHA仍然是公认的安全加密算法,较之MD5更为安全
HMAC
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。
BASE64的加密解密是双向的,可以求反解。
MD5、SHA以及HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。其中HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。
单向加密的用途主要是为了校验数据在传输过程中是否被修改。
http://security.group.iteye.com/group/wiki/1710-one-way-encryption-algorithm
对称加密和非对称加密 : 对称加密加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。非对称加密使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。
对称加密:
DES加密算法:
package demo.dcn.service.utils.security; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec; public class DESUtil1 { private static final String VIPARA = "01020304"; /** * 加密 */ public static byte[] encrypt(String strKey, byte[] data) throws Exception { Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); DESKeySpec desKeySpec = new DESKeySpec(strKey.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); IvParameterSpec iv = new IvParameterSpec(VIPARA.getBytes("UTF-8")); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); return cipher.doFinal(data); } /** * 解密 */ public static byte[] decrypt(String strKey, byte[] data) throws Exception { Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); DESKeySpec desKeySpec = new DESKeySpec(strKey.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey secretKey = keyFactory.generateSecret(desKeySpec); IvParameterSpec iv = new IvParameterSpec(VIPARA.getBytes("UTF-8")); cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); byte[] retByte = cipher.doFinal(data); return retByte; } public static String encrypt(String strKey, String data) throws Exception { byte[] encryptedData = encrypt(strKey, data .getBytes("UTF-8")); return Base64.encodeBase64String(encryptedData); } public static String decrypt(String strKey, String base64_str) throws Exception { byte[] encrypted = Base64.decodeBase64(base64_str); byte[] decryptedData = decrypt(strKey, encrypted); return new String(decryptedData, "UTF-8"); } }}
AES对称加密算法,高级加密
package demo.dcn.service.utils.security; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class AESUtil { private static final String VIPARA = "0102030405060708"; /** * android java python通用AES加密方法 * * @param strKey 为16 24 32位 =>对应的加密位数为128 192 256 * @param data 明文数据 * @return * @throws Exception */ public static byte[] encrypt(String strKey, byte[] data) throws Exception { IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes("UTF-8")); SecretKeySpec key = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv); byte[] encryptedData = cipher.doFinal(data); return encryptedData; } /** * android java python通用AES解密方法 * * @param strKey 为16 24 32位 =>对应的加密位数为128 192 256 * @param encrypted 密文数据 * @return * @throws Exception */ public static byte[] decrypt(String strKey, byte[] encrypted) throws Exception { IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes("UTF-8")); SecretKeySpec key = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key, zeroIv); byte[] decryptedData = cipher.doFinal(encrypted); return decryptedData; } //AES加密 public static String encrypt(String strKey, String data) throws Exception { byte[] encryptedData = encrypt(strKey, data .getBytes("UTF-8")); return Base64.encodeBase64String(encryptedData); } //AES解密 public static String decrypt(String strKey, String base64_str) throws Exception { byte[] encrypted = Base64.decodeBase64(base64_str); byte[] decryptedData = decrypt(strKey, encrypted); return new String(decryptedData, "UTF-8"); } }
RSA非对称加密算法
package demo.dcn.service.utils.security; public class KeyPairStr { private String publicKeyStr; private String privateKeyStr; public KeyPairStr() { } public KeyPairStr(String publicKeyStr, String privateKeyStr) { this.publicKeyStr = publicKeyStr; this.privateKeyStr = privateKeyStr; } public String getPublicKeyStr() { return publicKeyStr; } public void setPublicKeyStr(String publicKeyStr) { this.publicKeyStr = publicKeyStr; } public String getPrivateKeyStr() { return privateKeyStr; } public void setPrivateKeyStr(String privateKeyStr) { this.privateKeyStr = privateKeyStr; } }
package demo.dcn.service.utils.security; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * RSA 1024位加密算法 比较慢可以用于前台端加密解密方式 相对比较安全 */ public class RSAUtil { /** * 指定加密算法为RSA */ private static final String ALGORITHM = "RSA"; /** * 密钥长度,用来初始化 */ private static final int KEYSIZE = 1024; static { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); } /** * 生成密钥对,返回对应的公钥和私钥 * * @return * @throws Exception */ public static Map<String, String> generateKeyPairStr() throws Exception { Map<PublicKey, PrivateKey> keypair = generateKeyPair(); PublicKey publicKey = (PublicKey) keypair.keySet().toArray()[0]; PrivateKey privateKey = keypair.get(publicKey); byte[] pk = publicKey.getEncoded(); byte[] privk = privateKey.getEncoded(); String strpk = Base64.encodeBase64String(pk); String strprivk = Base64.encodeBase64String(privk); Map<String, String> keypairStr = new HashMap<>(); keypairStr.put(strpk, strprivk); return keypairStr; } public static KeyPairStr generateKeyPairStrToBean() throws Exception { Map<PublicKey, PrivateKey> keypair = generateKeyPair(); PublicKey publicKey = (PublicKey) keypair.keySet().toArray()[0]; PrivateKey privateKey = keypair.get(publicKey); byte[] pk = publicKey.getEncoded(); byte[] privk = privateKey.getEncoded(); String strpk = Base64.encodeBase64String(pk); String strprivk = Base64.encodeBase64String(privk); return new KeyPairStr(strpk, strprivk); } /** * 生成密钥对 * * @throws Exception */ public static Map<PublicKey, PrivateKey> generateKeyPair() throws Exception { Map<PublicKey, PrivateKey> keypair = new HashMap<>(); /** 为RSA算法创建一个KeyPairGenerator对象 */ KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM, "BC"); /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */ keyPairGenerator.initialize(KEYSIZE); /** 生成密匙对 */ KeyPair keyPair = keyPairGenerator.generateKeyPair(); /** 得到公钥 */ PublicKey publicKey = keyPair.getPublic(); /** 得到私钥 */ PrivateKey privateKey = keyPair.getPrivate(); keypair.put(publicKey, privateKey); return keypair; } /** * 公钥加密 * * @param source * @param base64_publicKey * @return base64编码的密文 * @throws Exception */ public static String encryptToBase64(byte[] source, String base64_publicKey) throws Exception { X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(Base64.decodeBase64(base64_publicKey)); KeyFactory keyf = KeyFactory.getInstance(ALGORITHM, "BC"); PublicKey pubkey2 = keyf.generatePublic(pubX509); return encryptToBase64(source, pubkey2); } /** * 公钥加密 * * @param source * @param base64_publicKey * @return 密文数组 * @throws Exception */ public static byte[] encrypt(byte[] source, String base64_publicKey) throws Exception { X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(Base64.decodeBase64(base64_publicKey)); KeyFactory keyf = KeyFactory.getInstance(ALGORITHM, "BC"); PublicKey pubkey2 = keyf.generatePublic(pubX509); return encrypt(source, pubkey2); } /** * 加密方法:公钥加密 * * @param source 源数据 * @return base64编码的密文 * @throws Exception */ public static String encryptToBase64(byte[] source, Key publicKey) throws Exception { byte[] b1 = encrypt(source, publicKey); return Base64.encodeBase64String(b1); } /** * 加密方法:公钥加密 * * @param source 源数据 * @return 密文数组 * @throws Exception */ public static byte[] encrypt(byte[] source, Key publicKey) throws Exception { /** 得到Cipher对象来实现对源数据的RSA加密 */ Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, publicKey); /** 执行加密操作 */ byte[] b1 = cipher.doFinal(source); return b1; } /** * 私钥解密 * * @param data * @param base64_privateKey * @return 明文数组 * @throws Exception */ public static byte[] decrypt(byte[] data, String base64_privateKey) throws Exception { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(base64_privateKey)); KeyFactory keyf = KeyFactory.getInstance(ALGORITHM, "BC"); PrivateKey privateKey = keyf.generatePrivate(priPKCS8); return decrypt(data, privateKey); } /** * 私钥解密 * * @param data * @param base64_privateKey * @return 明文 * @throws Exception */ public static String decryptToString(byte[] data, String base64_privateKey) throws Exception { PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(base64_privateKey)); KeyFactory keyf = KeyFactory.getInstance(ALGORITHM, "BC"); PrivateKey privkey = keyf.generatePrivate(priPKCS8); return decryptToString(data, privkey); } /** * 私钥解密 * * @param data 密文 * @return 明文 * @throws Exception */ public static String decryptToString(byte[] data, Key privateKey) throws Exception { return new String(decrypt(data, privateKey)); } /** * 私钥解密 * * @param data 密文 * @return 明文数组 * @throws Exception */ public static byte[] decrypt(byte[] data, Key privateKey) throws Exception { /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */ Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, privateKey); /** 执行解密操作 */ byte[] b = cipher.doFinal(data); return b; } } package cn.com.wangzha.utils; import java.security.MessageDigest; /** * @author zhangkun * @create 2018-12-27 9:51 PM * @desc **/ sha1加密: public class Sha1 { private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; /** * Takes the raw bytes from the digest and formats them correct. * * @param bytes the raw bytes from the digest. * @return the formatted bytes. */ private static String getFormattedText(byte[] bytes) { int len = bytes.length; StringBuilder buf = new StringBuilder(len * 2); // 把密文转换成十六进制的字符串形式 for (int j = 0; j < len; j++) { buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]); buf.append(HEX_DIGITS[bytes[j] & 0x0f]); } return buf.toString(); } public static String encode(String str) { if (str == null) { return null; } try { MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); messageDigest.update(str.getBytes()); return getFormattedText(messageDigest.digest()); } catch (Exception e) { throw new RuntimeException(e); } } }
加密分组算法模式:
ECB(Electronic Code Book电子密码本)模式
ECB模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。
优点: 1.简单; 2.有利于并行计算; 3.误差不会被扩散;
缺点: 1.不能隐藏明文的模式; 2.可能对明文进行主动攻击;
因此,此模式适于加密小消息。
CBC(Cipher Block Chaining,加密块链)模式
优点: 不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。
缺点: 1.不利于并行计算; 2.误差传递; 3.需要初始化向量IV
CFB(Cipher FeedBack Mode,加密反馈)模式
优点:
1.隐藏了明文模式; 2.分组密码转化为流模式; 3.可以及时加密传送小于分组的数据;
缺点: 1.不利于并行计算; 2.误差传送:一个明文单元损坏影响多个单元; 3.唯一的IV;
OFB(Output FeedBack,输出反馈)模式
优点: 1.隐藏了明文模式; 2.分组密码转化为流模式; 3.可以及时加密传送小于分组的数据;
缺点: 1.不利于并行计算; 2.对明文的主动攻击是可能的; 3.误差传送:一个明文单元损坏影响多个单元;
找了一些资料,做一写demo,还没有完全掌握密码学。 学习笔记先做在这里。
发表评论
-
Java 设计模式源码
2020-08-17 20:17 141经过一段时间学习和实践,整理了绝大多数设计模式源码demo 。 ... -
mac ngrok 使用
2018-12-20 18:22 876ngrok 是一个反向代理,通过在公共端点和本 ... -
Java元组学习
2018-12-19 15:38 622在Java 中我们平时用的接口和方法 只是单一 ... -
密码学2 密码安全注意
2018-11-30 15:11 6081.Java API支持 位于java.security包及子 ... -
base64 和 base32 源码解析
2018-11-30 14:19 1484package com.zd.demo; import ... -
maven 常用命令
2018-01-22 14:43 365mvn compile 编译源代码 mvn test-comp ... -
sql语法
2017-09-05 11:40 1按照查询in里条件排序sql SELECT * from p ... -
sql语法
2017-09-05 11:06 382按照查询in里条件排序sql SELECT * from p ... -
上传excel 通过url下载文件
2017-07-06 16:22 1058/** * 下载图片 */ ... -
idea使用,破解,mybatis plugin使用破解
2017-03-21 09:30 1176idea 最新激活方式:http://blog.csdn.ne ... -
多线程实现原理并发机制
2017-03-07 20:29 820进程: 查询百度大致可以理解为一段具有独 ... -
网络编程TCP/IP协议组
2017-03-04 13:42 559TCP/IP是个协议组: 主要可以分为4层,分别是应 ... -
Guava包的ListenableFuture解析
2016-10-09 13:40 1045package com.downjoy.test.guava. ... -
spring+guava事件异步分发处理
2016-10-09 09:56 4371Guava是Google开源的一个Java基础类库,它在Goo ... -
httpUtil工具和apche httpclient 工具类使用
2016-09-26 15:38 2411httpUtil请求网络请求工具: package demo ... -
mongodb+spring +morphia完整版框架搭建
2016-09-09 10:22 5716Morphia是一个开放源代 ... -
mongodb注解详解
2016-09-06 09:26 40551、@Entity 如果你想通过Morphia把你的对 ... -
自定义MD5加盐加密方式代码实现
2016-09-02 16:45 5061按照自己的理解对密码加盐加密。当用户注册时候会先生成盐值 ... -
kafka
2016-08-11 14:08 722Kafka is a distributed,partiti ... -
dubbo+zookeeper构建高可用分布式集群
2016-08-24 09:47 4966(1) 当服务越来越多时, ...
相关推荐
《应用密码学:协议、算法与C源程序》是一本深入浅出的密码学教材,旨在帮助读者全面理解和掌握密码学的基本概念、协议和算法。密码学是信息安全领域的重要组成部分,它涉及到数据加密、身份认证、消息完整性以及...
计算机密码学试题 计算机密码学是研究秘密通信的原理和破译密码的方法的一门科学。它包含两个相互对立的分支:密码分析和密码编码学。密码分析是研究破译密码的方法,而密码编码学是研究设计和实现安全密码的方法。...
### 密码学基础知识及其传统加密技术概览 #### 密码学概念解析 密码学是一门历史悠久且不断发展壮大的学科,它不仅涉及到数学、计算机科学等多个领域,而且与信息安全紧密相关。简单来说,密码学关注的是如何在不...
现代密码学是一门涵盖广泛领域的学科,它涉及信息安全、数据保护和网络安全的核心技术。杨波教授的《现代密码学》可能深入浅出地讲解了这一领域的重要理论与实践。密码学是信息技术中的基石,它的主要目标是确保数据...
《应用密码学》是信息安全领域的一门重要课程,由胡向东教授编著的教材和配套课件,旨在深入浅出地介绍密码学的基本原理、技术和应用。密码学是一门研究如何实现信息安全,保护数据免受未经授权访问、篡改或窃取的...
密码学是一门涉及信息安全、编码理论和计算复杂性理论的学科,主要研究如何在不安全的环境中保护数据的隐私和完整性。在中国科学技术大学(中科大)的本科教育中,密码学是一门重要的课程,旨在培养学生对加密算法、...
《计算机密码学 经典教材》是卢开澄所编著的一本关于密码学的专业书籍。本书详细介绍了密码学的基础理论和现代加密算法,特别强调了在电子商务和电子政务中的应用。全书共分为13章,内容涵盖了密码学的基本概念、...
现代密码学—原理与协议,讲解了各种现代密码学,非常详细 《现代密码学:原理与协议》内容简介:密码学在确保数据的私密性和完整性,以及计算机网络的安全性方面扮演了关键角色。乔纳森·卡茨和耶胡达·林德尔所著...
"现代密码学教程 谷利泽答案" 现代密码学是一门研究信息安全的科学,旨在保护信息系统的安全。下面是现代密码学教程的知识点总结: 一、密码学基础 * 密码学是研究信息安全的科学,分为密码编码学和密码分析学。 ...
在密码学领域,应用密码学是研究如何在实际系统中安全地使用密码技术的学科。这个学科涵盖了加密算法、身份认证、数据完整性、密钥管理等多个方面,旨在保护信息的安全性和隐私。本压缩包文件“应用密码学习题答案....
"应用密码学&现代密码学"这个主题涵盖了密码学的基本原理、实际应用以及最新的发展动态。这两本参考资料——《现代密码学理论与实践》和《应用密码学》——很可能会深入讨论这些方面。 首先,密码学的基本原理包括...
西安电子科技大学的密码学课件是一系列深入探讨密码学核心概念的教学资料,涵盖了编码、解码以及相关的加密机制。在密码学中,编码是将原始信息转化为不可读形式的过程,而解码则是恢复这些信息的过程,这两者在信息...
密码学是信息技术安全领域的重要分支,它涉及到一系列用于保护数据安全、确保信息机密性、完整性和认证的技术。本资源包含密码学课程设计的相关代码和资料,特别关注RSA和DES这两种经典的加密算法。 RSA(Rivest-...
密码学是一门涉及信息安全、数据保护以及网络安全的学科,它主要研究如何在不安全的环境中进行安全通信。在这个“密码学实践源代码”的程序实践中,我们可以深入理解密码学的一些核心概念和技术,这些技术广泛应用于...
根据给定文件中的标题、描述、标签以及部分内容,我们可以从中提炼出关于密码学的重要知识点。 ### 密码学概述 密码学(Cryptography)源于希腊语“Kruptos”(意为隐藏)与“graphein”(意为书写),其核心在于...
《经典密码学与现代密码学》是一本深入探讨密码学领域的专著,涵盖了从古代密码到现代加密技术的广泛知识。密码学是信息安全的核心组成部分,它涉及到如何在不安全的环境中保护数据的机密性、完整性和可用性。这本...