JavaMD5和SHA256等常用加密算法
发布时间:2025-05-21 08:58:49 发布人:远客网络
一、JavaMD5和SHA256等常用加密算法
前言
我们在做java项目开发的时候,在前后端接口分离模式下,接口信息需要加密处理,做签名认证,还有在用户登录信息密码等也都需要数据加密。信息加密是现在几乎所有项目都需要用到的技术,身份认证、单点登陆、信息通讯、支付交易等场景中经常会需要用到加密算法,所谓加密算法,就是将原本的明文通过一系列算法操作变成密文。
我们在做java项目开发的时候,在前后端接口分离模式下,接口信息需要加密处理,做签名认证,还有在用户登录信息密码等也都需要数据加密。信息加密是现在几乎所有项目都需要用到的技术,身份认证、单点登陆、信息通讯、支付交易等场景中经常会需要用到加密算法,所谓加密算法,就是将原本的明文通过一系列算法操作变成密文。
BASE严格地说,属于编码格式,而非加密算法MD(MessageDigestalgorithm,信息摘要算法)SHA(SecureHashAlgorithm,安全散列算法)HMAC(HashMessageAuthenticationCode,散列消息鉴别码)
加密算法中SHA1、SHA-224、SHA-256、SHA-384,和SHA-512,其中SHA-224、SHA-256、SHA-384,和SHA-512我们可以统称为SHA2加密算法
SHA加密算法的安全性要比MD5更高,而SHA2加密算法比SHA1的要高。其中SHA后面的数字表示的是加密后的字符串长度,SHA1默认会产生一个160位的信息摘要。
MD5信息摘要算法(英语:MD5Message-DigestAlgorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hashvalue),用于确保信息传输完整一致。
压缩性:无论数据长度是多少,计算出来的MD5值长度相同
容易计算性:由原数据容易计算出MD5值
抗修改性:即便修改一个字节,计算出来的MD5值也会巨大差异
抗碰撞性:知道数据和MD5值,很小概率找到相同MD5值相同的原数据
准确来讲,MD5不是一种加密算法,而是一种摘要算法,MD5能将明文输出为128bits的字符串,这个字符串是无法再被转换成明文的。网上一些MD5解密网站也只是保存了一些字符串对应的md5串,通过已经记录的md5串来找出原文。
我做过的几个项目中经常见到MD5用在加密上的场景。比如对密码的加密,生成一个密码后,使用MD5生成一个128位字符串保存在数据库中,用户输入密码后也先生成MD5串,再去数据库里比较。因此我们在找回密码时是无法得到原来的密码的,因为明文密码根本不会被保存。
安全散列算法(英语:SecureHashAlgorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。
2005年8月17日的CRYPTO会议尾声中王小云、姚期智、姚储枫再度发表更有效率的SHA-1攻击法,能在2的63次方个计算复杂度内找到碰撞。
也就是说SHA-1加密算法有碰撞的可能性,虽然很小。
HMAC是密钥相关的哈希运算消息认证码(Hash-basedMessageAuthenticationCode)的缩写,由H.Krawezyk,M.Bellare,R.Canetti于1996年提出的一种基于Hash函数和密钥进行消息认证的方法,并于1997年作为RFC2104被公布,并在IPSec和其他网络协议(如SSL)中得以广泛应用,现在已经成为事实上的Internet安全标准。它可以与任何迭代散列函数捆绑使用。
HMAC算法更像是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的Hash算法
如果要使用加密,推荐使用SHA256、SHA384、SHA512以及HMAC-SHA256、HMAC-SHA384、HMAC-SHA512这几种算法。
对称加密算法是应用比较早的算法,在数据加密和解密的时用的都是同一个密钥,这就造成了密钥管理困难的问题。常见的对称加密算法有DES、3DES、AES128、AES192、AES256(默认安装的JDK尚不支持AES256,需要安装对应的jce补丁进行升级jce1.7,jce1.8)。其中AES后面的数字代表的是密钥长度。对称加密算法的安全性相对较低,比较适用的场景就是内网环境中的加解密。
所谓对称加密,就是通过密钥加密后可以再通过密钥解密。我接触过的某个国企现在内部就是采用AES的方式实现集成登陆。第三方系统提供一个接收用户信息的接口,该国企将用户信息AES加密后通过这个接口传递给第三方系统,第三方系统自行实现登陆操作。这里需要注意的是密钥十分重要,如果密钥丢失,就有信息泄漏的风险。
加密盐也是比较常听到的一个概念,盐就是一个随机字符串用来和我们的加密串拼接后进行加密。
加盐主要是为了提供加密字符串的安全性。假如有一个加盐后的加密串,黑客通过一定手段这个加密串,他拿到的明文,并不是我们加密前的字符串,而是加密前的字符串和盐组合的字符串,这样相对来说又增加了字符串的安全性。
不可逆加密:SHA256、SHA384、SHA512以及HMAC-SHA256、HMAC-SHA384、HMAC-SHA512
二、Java加密和数字签名
1、 Java加密和数字签名本文主要谈一下密码学中的加密和数字签名以及其在java中如何进行使用对密码学有兴趣的伙伴推荐看 Bruce Schneier的著作 Applied Crypotography在jdk的发行版本中安全性方面有了很大的改进也提供了对RSA算法的直接支持现在我们从实例入手解决问题(本文仅是作为简单介绍)
2、这是一种与消息认证码结合使用以确保消息完整性的技术主要使用单向散列函数算法可用于检验消息的完整性和通过散列密码直接以文本形式保存等目前广泛使用的算法有MD MD SHA jdk对上面都提供了支持在java中进行消息摘要很简单 java security MessageDigest提供了一个简易的操作方法
3、/***MessageDigestExample java*Copyright*/ import java security MessageDigest;/***单一的消息摘要算法不使用密码可以用来对明文消息(如密码)隐藏保存*/ public class MessageDigestExample{ public static void main(String[] args) throws Exception{ if(args length!=){ System err println( Usage:java MessageDigestExample text); System exit();}
4、 byte[] plainText=args[ ] getBytes( UTF);
5、//使用getInstance(算法)来获得消息摘要这里使用SHA的位算法 MessageDigest messageDigest=MessageDigest getInstance( SHA);
6、 System out println( \n+messageDigest getProvider() getInfo());//开始使用算法 messageDigest update(plainText); System out println( \nDigest:);//输出算法运算结果 System out println(new String(messageDigest digest() UTF));}}还可以通过消息认证码来进行加密实现 javax crypto Mac提供了一个解决方案有兴趣者可以参考相关API文档本文只是简单介绍什么是摘要算法
7、这里补充另一个运用消息摘要的方式加密的例子: public class TestEncrypt{
8、/***@param strSrc:strSrc is a string will be encrypted*@param encName: encName is the algorithm name will be used* encName dafault to MD*@return String*/ public String Encrypt(String strSrc String encName){
9、 MessageDigest md= null; String strDes= null;
10、 byte[] bt= strSrc getBytes(); try{ if(encName== null|| encName equals()){ encName= MD;} md= MessageDigest getInstance(encName); md update(bt); strDes= bytes Hex(md digest());//to HexString} catch(NoSuchAlgorithmException e){ System out println( Invalid algorithm); return null;} return strDes;}
11、 public String bytes Hex(byte[] bts){ String des=; String tmp= null; for(int i=; i< bts length; i++){ tmp=(Integer toHexString(bts[i]& xFF)); if(tmp length()==){ des+=;} des+= tmp;} return des;}
12、 public static void main(String[]args){ TestEncrypt te= new TestEncrypt(); String strSrc=可以加密汉字 Oh and english; System out println( Source String:+ strSrc); System out println( Encrypted String:); System out println( Use Def:+ te Encrypt(strSrc null)); System out println( Use MD:+ te Encrypt(strSrc MD)); System out println( Use SHA:+ te Encrypt(strSrc SHA)); System out println( Use SHA:+ te Encrypt(strSrc SHA));}}
13、另外在javawebparts中的 RequestHelpers里的generateGUID方法也涉及到了MD的方法代码如下: public static String generateGUID(HttpServletRequest request){
14、 String out=; try{// Construct a string that is prised of:// Remote IP Address+ Host IP Address+ Date(yyyyMMdd)+// Time(hhmmssSSa)+ Requested Path+ Session ID+// HashCode Of ParameterMap StringBuffer***= new StringBuffer();*** append(request getRemoteAddr()); InetAddress ia= InetAddress getLocalHost();*** append(ia getHostAddress());*** append(new SimpleDateFormat( yyyyMMddhhmmssSSa) format(new Date())); String path= request getServletPath(); String pathInfo= request getPathInfo(); if(pathInfo!= null){ path+= pathInfo;}*** append(path);*** append(request getSession(false));*** append(request getParameterMap() hashCode()); String str=*** toString();// Now encode the string using an MD encryption algorithm MessageDigest md= MessageDigest getInstance( md); md update(str getBytes()); byte[] digest= md digest(); StringBuffer hexStr= new StringBuffer(); for(int i=; i< digest length; i++){ str= Integer toHexString( xFF& digest[i]); if(str length()<){ str=+ str;} hexStr append(str);} out= hexStr toString();} catch(NoSuchAlgorithmException nsae){ log error(nsae);} catch(UnknownHostException uhe){ log error(uhe);}// Return the encrypted string It should be unique based on the// ponents that prise the plain text string and should always be// characters thanks to the MD algorithm return out;
15、消息摘要只能检查消息的完整性但是单向的对明文消息并不能加密要加密明文的消息的话就要使用其他的算法要确保机密性我们需要使用私钥密码术来交换私有消息
16、这种最好理解使用对称算法比如 A用一个密钥对一个文件加密而B读取这个文件的话则需要和A一样的密钥双方共享一个私钥(而在web环境下私钥在传递时容易被侦听)
17、使用私钥加密的话首先需要一个密钥可用javax crypto KeyGenerator产生一个密钥(java security Key)然后传递给一个加密工具(javax crypto Cipher)该工具再使用相应的算法来进行加密主要对称算法有 DES(实际密钥只用到位) AES(支持三种密钥长度位)通常首先位其他的还有DESede等 jdk种也提供了对对称算法的支持以下例子使用AES算法来加密
18、/***PrivateExmaple java*Copyright*/ import javax crypto Cipher; import javax crypto KeyGenerator; import java security Key;
19、/***私鈅加密保证消息机密性*/ public class PrivateExample{ public static void main(String[] args) throws Exception{ if(args length!=){ System err println( Usage:java PrivateExample<text>); System exit();} byte[] plainText=args[ ] getBytes( UTF);
20、//通过KeyGenerator形成一个key System out println( \nStart generate AES key); KeyGenerator keyGen=KeyGenerator getInstance( AES); keyGen init(); Key key=keyGen generateKey(); System out println( Finish generating DES key);
21、//获得一个私鈅加密类Cipher ECB是加密方式 PKCS Padding是填充方法 Cipher cipher=Cipher getInstance( AES/ECB/PKCS Padding); System out println( \n+cipher getProvider() getInfo());
22、//使用私鈅加密 System out println( \nStart encryption:); cipher init(Cipher ENCRYPT_MODE key); byte[] cipherText=cipher doFinal(plainText); System out println( Finish encryption:); System out println(new String(cipherText UTF));
23、 System out println( \nStart decryption:); cipher init(Cipher DECRYPT_MODE key); byte[] newPlainText=cipher doFinal(cipherText); System out println( Finish decryption:);
24、 System out println(new String(newPlainText UTF));
25、上面提到私钥加密需要一个共享的密钥那么如何传递密钥呢?web环境下直接传递的话很容易被侦听到幸好有了公钥加密的出现公钥加密也叫不对称加密不对称算法使用一对密钥对一个公钥一个私钥使用公钥加密的数据只有私钥能解开(可用于加密)同时使用私钥加密的数据只有公钥能解开(签名)但是速度很慢(比私钥加密慢到倍)公钥的主要算法有RSA还包括Blowfish Diffie Helman等 jdk种提供了对RSA的支持是一个改进的地方
26、/***PublicExample java*Copyright*/ import java security Key; import javax crypto Cipher; import java security KeyPairGenerator; import java security KeyPair;/***一个简单的公鈅加密例子 Cipher类使用KeyPairGenerator生成的公鈅和私鈅*/ public class PublicExample{ public static void main(String[] args) throws Exception{ if(args length!=){ System err println( Usage:java PublicExample<text>); System exit();}
27、 byte[] plainText=args[ ] getBytes( UTF);//构成一个RSA密钥 System out println( \nStart generating RSA key); KeyPairGenerator keyGen=KeyPairGenerator getInstance( RSA); keyGen initialize(); KeyPair key=keyGen generateKeyPair(); System out println( Finish generating RSA key);
28、//获得一个RSA的Cipher类使用公鈅加密 Cipher cipher=Cipher getInstance( RSA/ECB/PKCS Padding); System out println( \n+cipher getProvider() getInfo());
29、 System out println( \nStart encryption); cipher init(Cipher ENCRYPT_MODE key getPublic()); byte[] cipherText=cipher doFinal(plainText); System out println( Finish encryption:); System out println(new String(cipherText UTF));
三、Java 加密解密的方法都有哪些
1、加密解密并非java才有的,所有编程语言都有加密和解密。
2、目前的加密解密主要可分为以下2大类:
3、对称秘钥加密:如DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法等。其主要特点是加密方和解密方都有同一个密码,加密方和解密方可以使用秘钥任意加密解密。
4、非对称密码加密:这种加密方式加密方仅有加密秘钥,对加密后的密文无法反向解密,解密方仅有解密秘钥,无法对明文进行加密。
5、另外还有一些摘要算法,比如MD5和HASH此类算法不可逆,但经常用来作为确认字段或者对一些重要匹配信息签名防止明文内容被修改。