美文网首页Java 杂谈Java
什么是加密算法?

什么是加密算法?

作者: java面试笔试 | 来源:发表于2018-08-22 14:20 被阅读0次

    Java的加密知识也是Java常见的领域之一,加密技术的底层确实很复杂,运用了大量的数学知识,要弄明白非常复杂。但是Java语言中运用密码加密工具却是非常简单。我们在Java里面运用这些加密技术,只需要把原理和使用场景等搞明白就可以了,具体底层实现不用研究。

    常用的加密算法有对称加密算法,非对称加密算法,哈希算法,数字签名等几类。    

    对称加密顾名思义就是加密和解密是对称的,加密时用一个秘钥去加密,解密时用同一个秘钥去解密,由信息发送方和接收方共同约定一个秘钥。缺点是风险都在这个秘钥上面,一旦被窃取,信息会暴露。所以安全级别不够高。常用对称加密算法有DES,3DES,AES等。在jdk中也都有封装。

    非对称加密,顾名思义就是加密与解密的过程不是对称的,不是用的同一个秘钥。非对称加密有个公私钥对的概念,也就是有两把秘钥,一把是公钥,一把是私钥,一对公私钥有固定的生成方法,在加密的时候,用公钥去加密,接收方再用对应的私钥去解密。使用时可以由接收方生成公私钥对,然后将公钥传给加密方,这样私钥不会在网络中传输,没有被窃取的风险。比如github底层的ssh协议就是公私钥非对称加密。并且公钥是可以由私钥推导出来的,反过来却不行,由通过公钥无法推导出私钥。常用算法有RSA,ECC等。ECC也是比特币底层用的比较多的算法。通过和对称加密的对比,可以看到,非对称加密解决了秘钥传输中的安全问题。

    哈希算法,简单说就是将任意数据都转换成一个固定长度的字符串。通过哈希后的值几乎无法推导出原文。而且两个不同的原文哈希后结果一定不同。常用算法有MD5,SHA256等等。常用场景,md5常用场景是数据库的密码存储。sha256在挖矿中可以用到。

    非对称加密也有一个问题,就是内容在发送前可能被篡改,因为公钥是有可能被窃取的,所以窃取者完全可以改为发送别的内容。

    解决的办法就是数字签名。数字签名和非对称加密是反过来的,也是有公私钥对,但是是用私钥签名,用公钥去验证签名。比如发送方除了发送用公钥加密后的密文,还要发送签名,签名内容通常是密文哈希后的字符串,接收方首先验证签名是否正确,如果正确那么密文解密后就是真正需要并且没有被篡改过的内容。注意,签名和非对称用的是两对不同的公私钥。

    上面是对几个加密算法的一个简单讲解,除了上面的还有base58等,比特币底层安全也是依赖于加密。后面会一个一个介绍要用到的加密算法的介绍和使用,但是仅仅是使用,底层不会讲。

    MD5

    MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。

    MD5算法具有以下特点:

    1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。

    2、容易计算:从原数据计算出MD5值很容易。

    3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

    4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

    MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等。

    JDK就自带了md5加密算法,直接调用很方便。需要引入一个类:

    import java.security.MessageDigest;

    首先创建一个springboot项目,加上一个web以来,内容如下:

    SHA256

    学Java的对哈希算法都不陌生,毕竟每个类都有hashCode方法。

    散列算法(Hash Algorithm),又称哈希算法,杂凑算法,是一种从任意文件中创造小的数字「指纹」的方法。与指纹一样,散列算法就是一种以较短的信息来保证文件唯一性的标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。因此,当原有文件发生改变时,其标志值也会发生改变,从而告诉文件使用者当前的文件已经不是你所需求的文件。

    一个优秀的 hash 算法,将能实现:

    正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。

    逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。

    输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。

    冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。即对于任意两个不同的数据块,其hash值相同的可能性极小;对于一个给定的数据块,找到和它hash值相同的数据块极为困难。

    但在不同的使用场景中,如数据结构和安全领域里,其中对某一些特点会有所侧重。

    安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。

    SHA家族的五个算法,分别是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512。主要适用于数字签名标准(DigitalSignature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。比特币里面的就是SHA-256算法。

    说简单一些,就是对一个对象的多个关键不重复信息组合起来,通过算法生成一个加密字符串。

    继续上一个项目,在对应的包下建一个工具类:

    package btcdemo.btcdemo.security;

    public class Sha256Utils

    引入的加密类和md5一样:

    import java.security.MessageDigest;

    下面是算法的具体内容:

    下面是算法的测试类内容:

    运行可以看到如下结果:

    目前目录结构如下:

    项目代码:https://github.com/guoyb1990/btc-demo.git

    BASE64&BASE58

    Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。

    Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读。

    Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用‘=’,因此编码后输出的文本末尾可能会出现1或2个‘=’。 

    jdk的工具包中就自带base64的工具类,使用base64的方法也非常简单,先新建一个工具类:

    base64是可逆的,加密解密内容如下:

    可以看到使用非常简单,下面是测试类内容:

    执行测试方法,结果如下:

    可以看到base64非常简单。

    base58和base64一样是一种二进制转可视字符串的算法,主要用来转换大整数值。区别是,转换出来的字符串,去除了几个看起来会产生歧义的字符,如 0 (零), O (大写字母O), I (大写的字母i) and l (小写的字母L) ,和几个影响双击选择的字符,如/, +。结果字符集正好58个字符(包括9个数字,24个大写字母,25个小写字母)。不同的应用实现中,base58 最后查询的字母表可能不同,所以没有具体的标准。

    可以看出,base58是base64的一种人性化的版本,是站在使用者的角度考虑的。

    新建一个Base58的工具类,目录结构如下:

    工具类的大概内容结构如下:

    因为内容过多,可以通过下载源码查看。

    下面是测试代码:

    运行结果如下:

    可以看到,base58的使用方法是一样的。

    项目代码:https://github.com/guoyb1990/btc-demo.git

    公众号:javafirst

    相关文章

      网友评论

        本文标题:什么是加密算法?

        本文链接:https://www.haomeiwen.com/subject/xpxyiftx.html