java解密_JAVA加解密

本文详细介绍了加密技术的基本概念,包括明文、密文、算法和密钥,并通过简单示例解释了对称加密和非对称加密。接着列举了常见的加密算法,如对称加密的AES、3DES和非对称加密的RSA等,同时提供了这些算法在JAVA中的具体实现代码示例。此外,还提及了MD5和SHA等哈希算法的应用。
摘要由CSDN通过智能技术生成

【前言】

本文简单的介绍了加密技术相关概念,最后总结了java中现有的加密技术以及使用方法和例子

【最简单的加密】

1.简单的概念

明文:加密前的信息

密文:机密后的信息

算法:加密或解密的算法

密钥:算法使用的钥匙(读作miyao,正确应该是miyue,但是大家都读miyao)

2.简单的例子

将123456每位数字都加1后得到234567,

其中123456就是明文,234567就是密文,加密密钥就是1,加密算法是每位加

3.对称加密和非对称加密

以上为例,

123456-->234567的加密密钥就是1,加密算法是每位+

234567-->123456的解密密钥也是1,解密算法是每位-

其中加密算法(+)和解密算法(-)相对称,这种加密算法就称作对称加密,

同样,如果加密算法和解密算法不对称就称之为非对称加密。

4.算法举例

众多的加密手段大致可以分为单项加密和双向加密。单项加密指通过对数据进行摘要计算生成密文,密文不可逆推还原,比如有Base64、MD5、SHA等;双向加密则相反,指可以把密文逆推还原成明文,其中双向加密又分为对称加密和非对称加密。对称加密是指数据使用者必须拥有同样的密钥才可以进行加密解密,就像大家共同约定了一组暗号一样,对称加密的手段有DES、3DES、AES、IDEA、RC4、RC5等;而非对称加密相对于对称加密而言,无需拥有同一组密钥,它是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,也就是说使用公开密钥进行数据加密,只有对应的私有密钥才能进行解密。此类的加密手段有RSA、DSA等

对称加密算法:DES算法,3DES算法,TDEA算法,Blowfish算法,RC5算法,IDEA算法,AES算法。

非对称加密算法:RSA、Elgamal、背包算法、Rabin、D-H、ECC。

经典的哈希算法:MD2、MD4、MD5 和 SHA-1(目的是将任意长输入通过算法变为固定长输出,且保证输入变化一点输出都不同,且不能反向解密)

5.经典算法实现

5.1:AES算法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.meng.study.security;importjava.security.SecureRandom;importjavax.crypto.Cipher;importjavax.crypto.KeyGenerator;importjavax.crypto.SecretKey;importjavax.crypto.spec.SecretKeySpec;public classAESUtil {/*** AES加密

*

*@paramcontent

* 待加密的内容

*@paramencryptKey

* 加密密钥

*@return加密后的byte[]

*@throwsException*/

public static byte[] aesEncryptToBytes(String content, String encryptKey) throwsException {

KeyGenerator kgen= KeyGenerator.getInstance("AES");

SecureRandom random= SecureRandom.getInstance("SHA1PRNG");

random.setSeed(encryptKey.getBytes());

kgen.init(128, random);

SecretKey secretKey= new SecretKeySpec(kgen.generateKey().getEncoded(), "AES");

Cipher cipher= Cipher.getInstance("AES");

cipher.init(Cipher.ENCRYPT_MODE, secretKey);return cipher.doFinal(content.getBytes("UTF-8"));

}/*** AES加密为base 64 code

*

*@paramcontent

* 待加密的内容

*@paramencryptKey

* 加密密钥

*@return加密后的base 64 code

*@throwsException*/

public static String aesEncrypt(String content, String encryptKey) throwsException {returnBASE64Util.base64Encode(aesEncryptToBytes(content, encryptKey));

}/*** AES解密

*

*@paramencryptBytes

* 待解密的byte[]

*@paramdecryptKey

* 解密密钥

*@return解密后的String

*@throwsException*/

public static String aesDecryptByBytes(byte[] encryptBytes, String decryptKey) throwsException {

KeyGenerator kgen= KeyGenerator.getInstance("AES");

SecureRandom random= SecureRandom.getInstance("SHA1PRNG");

random.setSeed(decryptKey.getBytes());

kgen.init(128, random);

SecretKey secretKey= new SecretKeySpec(kgen.generateKey().getEncoded(), "AES");

Cipher cipher= Cipher.getInstance("AES");

cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] decryptBytes =cipher.doFinal(encryptBytes);return newString(decryptBytes);

}/*** 将base 64 code AES解密

*

*@paramencryptStr

* 待解密的base 64 code

*@paramdecryptKey

* 解密密钥

*@return解密后的string

*@throwsException*/

public static String aesDecrypt(String encryptStr, String decryptKey) throwsException {returnaesDecryptByBytes(BASE64Util.base64Decode(encryptStr), decryptKey);

}

}

显示代码

5.2:3DES算法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.meng.study.security;importjava.io.UnsupportedEncodingException;importjavax.crypto.Cipher;importjavax.crypto.SecretKey;importjavax.crypto.spec.SecretKeySpec;importorg.apache.log4j.Logger;importcom.meng.study.cache.GuavaCacheUtil;/***

*@authorzhenbinmeng

**/

public classDESUtil {private static Logger logger = Logger.getLogger(DESUtil.class);//定义加密算法,DESede(即3DES)

private static final String DESede = "DESede";private static final String PASSWORD_CRYPT_KEY = "2015mengzhenbinStudyForSecurity@DESede";/*** 加密方法

*

*@paramsrc

* 源数据的字节数组

*@return

*/

public static byte[] encryptMode(byte[] src) {try{

SecretKey deskey= new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), DESede); //生成密钥

Cipher c1 = Cipher.getInstance(DESede); //实例化负责加密/解密的Cipher工具类

c1.init(Cipher.ENCRYPT_MODE, deskey); //初始化为加密模式

returnc1.doFinal(src);

}catch(Exception e) {

logger.error("DesUtil.encryptMode error", e);

e.printStackTrace();

}return null;

}/*** 加密方法(BASE64编码返回)

*

*@paramsrc

* 源数据的字节数组

*@return

*/

public static String encryptModeBase64(byte[] src) {try{

SecretKey deskey= new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), DESede); //生成密钥

Cipher c1 = Cipher.getInstance(DESede); //实例化负责加密/解密的Cipher工具类

c1.init(Cipher.ENCRYPT_MODE, deskey); //初始化为加密模式

returnBASE64Util.base64Encode(c1.doFinal(src));

}catch(Exception e) {

logger.error("DesUtil.encryptMode error", e);

e.printStackTrace();

}return null;

}/*** 解密函数

*

*@paramsrc

* 密文的字节数组

*@return

*/

public static byte[] decryptMode(byte[] src) {try{

SecretKey deskey= newSecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), DESede);

Cipher c1=Cipher.getInstance(DESede);

c1.init(Cipher.DECRYPT_MODE, deskey);//初始化为解密模式

returnc1.doFinal(src);

}catch(Exception e) {

logger.error("DesUtil.decryptMode error", e);

e.printStackTrace();

}return null;

}/*** 解密函数(BASE64解码后解密)

*

*@paramsrc

* 密文的字节数组

*@return

*/

public staticString decryptModeBase64(String src) {try{

SecretKey deskey= newSecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), DESede);

Cipher c1=Cipher.getInstance(DESede);

c1.init(Cipher.DECRYPT_MODE, deskey);//初始化为解密模式

return newString(c1.doFinal(BASE64Util.base64Decode(src)));

}catch(Exception e) {

logger.error("DesUtil.decryptMode error", e);

e.printStackTrace();

}return null;

}/** 根据字符串生成密钥字节数组

*

* @param keyStr 密钥字符串

*

* @return

*

* @throws UnsupportedEncodingException*/

public static byte[] build3DesKey(String keyStr) throwsUnsupportedEncodingException {byte[] key = new byte[24]; //声明一个24位的字节数组,默认里面都是0

byte[] temp = keyStr.getBytes("UTF-8"); //将字符串转成字节数组

/** 执行数组拷贝 System.arraycopy(源数组,从源数组哪里开始拷贝,目标数组,拷贝多少位)*/

if (key.length >temp.length) {//如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中

System.arraycopy(temp, 0, key, 0, temp.length);

}else{//如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中

System.arraycopy(temp, 0, key, 0, key.length);

}returnkey;

}

}

显示代码

5.3:MD5算法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.meng.study.security;importjava.security.MessageDigest;public classMD5Util {/*** 获取byte[]的md5值

*

*@parambytes

* byte[]

*@returnmd5

*@throwsException*/

public static byte[] md5(byte[] bytes) throwsException {

MessageDigest md= MessageDigest.getInstance("MD5");

md.update(bytes);returnmd.digest();

}/*** 获取字符串md5值

*

*@parammsg

*@returnmd5

*@throwsException*/

public static byte[] md5(String msg) throwsException {returnmd5(msg.getBytes());

}/*** 获取字符串md5值

*

*@parammsg

*@returnmd5

*@throwsException*/

public static String md5Hex(String msg) throwsException {byte[] messageDigest =md5(msg.getBytes());//Create Hex String

StringBuffer hexString = newStringBuffer();//字节数组转换为 十六进制 数

for (int i = 0; i < messageDigest.length; i++) {

String shaHex= Integer.toHexString(messageDigest[i] & 0xFF);if (shaHex.length() < 2) {

hexString.append(0);

}

hexString.append(shaHex);

}returnhexString.toString();

}/*** 结合base64实现md5加密

*

*@parammsg

* 待加密字符串

*@return获取md5后转为base64

*@throwsException*/

public static String md5Base64(String msg) throwsException {returnBASE64Util.base64Encode(md5(msg));

}

}

显示代码

5.4:SHA算法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.meng.study.security;importjava.security.MessageDigest;public classSHAUtil {public staticString SHA1(String decript) {try{

MessageDigest digest= java.security.MessageDigest.getInstance("SHA-1");

digest.update(decript.getBytes());byte messageDigest[] =digest.digest();//Create Hex String

StringBuffer hexString = newStringBuffer();//字节数组转换为 十六进制 数

for (int i = 0; i < messageDigest.length; i++) {

String shaHex= Integer.toHexString(messageDigest[i] & 0xFF);if (shaHex.length() < 2) {

hexString.append(0);

}

hexString.append(shaHex);

}returnhexString.toString();

}catch(Exception e) {

e.printStackTrace();

}return "";

}public staticString SHA(String decript) {try{

MessageDigest digest= java.security.MessageDigest.getInstance("SHA");

digest.update(decript.getBytes());byte messageDigest[] =digest.digest();//Create Hex String

StringBuffer hexString = newStringBuffer();//字节数组转换为 十六进制 数

for (int i = 0; i < messageDigest.length; i++) {

String shaHex= Integer.toHexString(messageDigest[i] & 0xFF);if (shaHex.length() < 2) {

hexString.append(0);

}

hexString.append(shaHex);

}returnhexString.toString();

}catch(Exception e) {

e.printStackTrace();

}return "";

}

}

显示代码

5.5:RSA算法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.meng.study.security;importjava.math.BigInteger;importjava.security.KeyFactory;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.NoSuchAlgorithmException;importjava.security.interfaces.RSAPrivateKey;importjava.security.interfaces.RSAPublicKey;importjava.security.spec.RSAPrivateKeySpec;importjava.security.spec.RSAPublicKeySpec;importjava.util.HashMap;importjavax.crypto.Cipher;public classRSAUtil {/*** 生成公钥和私钥

*

*@throwsNoSuchAlgorithmException

**/

public static HashMap getKeys() throwsNoSuchAlgorithmException {

HashMap map = new HashMap();

KeyPairGenerator keyPairGen= KeyPairGenerator.getInstance("RSA");

keyPairGen.initialize(1024);

KeyPair keyPair=keyPairGen.generateKeyPair();

RSAPublicKey publicKey=(RSAPublicKey) keyPair.getPublic();

RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate();

map.put("public", publicKey);

map.put("private", privateKey);returnmap;

}/*** 使用模和指数生成RSA公钥

* 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA

* /None/NoPadding】

*

*@parammodulus

* 模

*@paramexponent

* 指数

*@return

*/

public staticRSAPublicKey getPublicKey(String modulus, String exponent) {try{

BigInteger b1= newBigInteger(modulus);

BigInteger b2= newBigInteger(exponent);

KeyFactory keyFactory= KeyFactory.getInstance("RSA");

RSAPublicKeySpec keySpec= newRSAPublicKeySpec(b1, b2);return(RSAPublicKey) keyFactory.generatePublic(keySpec);

}catch(Exception e) {

e.printStackTrace();return null;

}

}/*** 使用模和指数生成RSA私钥

* 注意:【此代码用了默认补位方式,为RSA/None/PKCS1Padding,不同JDK默认的补位方式可能不同,如Android默认是RSA

* /None/NoPadding】

*

*@parammodulus

* 模

*@paramexponent

* 指数

*@return

*/

public staticRSAPrivateKey getPrivateKey(String modulus, String exponent) {try{

BigInteger b1= newBigInteger(modulus);

BigInteger b2= newBigInteger(exponent);

KeyFactory keyFactory= KeyFactory.getInstance("RSA");

RSAPrivateKeySpec keySpec= newRSAPrivateKeySpec(b1, b2);return(RSAPrivateKey) keyFactory.generatePrivate(keySpec);

}catch(Exception e) {

e.printStackTrace();return null;

}

}/*** 公钥加密

*

*@paramdata

*@parampublicKey

*@return*@throwsException*/

public static String encryptByPublicKey(String data, RSAPublicKey publicKey) throwsException {

Cipher cipher= Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, publicKey);//模长

int key_len = publicKey.getModulus().bitLength() / 8;//加密数据长度 <= 模长-11

String[] datas = splitString(data, key_len - 11);

String mi= "";//如果明文长度大于模长-11则要分组加密

for(String s : datas) {

mi+=bcd2Str(cipher.doFinal(s.getBytes()));

}returnmi;

}/*** 私钥解密

*

*@paramdata

*@paramprivateKey

*@return*@throwsException*/

public static String decryptByPrivateKey(String data, RSAPrivateKey privateKey) throwsException {

Cipher cipher= Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, privateKey);//模长

int key_len = privateKey.getModulus().bitLength() / 8;byte[] bytes =data.getBytes();byte[] bcd =ASCII_To_BCD(bytes, bytes.length);//如果密文长度大于模长则要分组解密

String ming = "";byte[][] arrays =splitArray(bcd, key_len);for (byte[] arr : arrays) {

ming+= newString(cipher.doFinal(arr));

}returnming;

}/*** ASCII码转BCD码

**/

public static byte[] ASCII_To_BCD(byte[] ascii, intasc_len) {byte[] bcd = new byte[asc_len / 2];int j = 0;for (int i = 0; i < (asc_len + 1) / 2; i++) {

bcd[i]= asc_to_bcd(ascii[j++]);

bcd[i]= (byte) (((j >= asc_len) ? 0x00 : asc_to_bcd(ascii[j++])) + (bcd[i] << 4));

}returnbcd;

}public static byte asc_to_bcd(byteasc) {bytebcd;if ((asc >= '0') && (asc <= '9'))

bcd= (byte) (asc - '0');else if ((asc >= 'A') && (asc <= 'F'))

bcd= (byte) (asc - 'A' + 10);else if ((asc >= 'a') && (asc <= 'f'))

bcd= (byte) (asc - 'a' + 10);elsebcd= (byte) (asc - 48);returnbcd;

}/*** BCD转字符串*/

public static String bcd2Str(byte[] bytes) {char temp[] = new char[bytes.length * 2], val;for (int i = 0; i < bytes.length; i++) {

val= (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);

temp[i* 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

val= (char) (bytes[i] & 0x0f);

temp[i* 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

}return newString(temp);

}/*** 拆分字符串*/

public static String[] splitString(String string, intlen) {int x = string.length() /len;int y = string.length() %len;int z = 0;if (y != 0) {

z= 1;

}

String[] strings= new String[x +z];

String str= "";for (int i = 0; i < x + z; i++) {if (i == x + z - 1 && y != 0) {

str= string.substring(i * len, i * len +y);

}else{

str= string.substring(i * len, i * len +len);

}

strings[i]=str;

}returnstrings;

}/*** 拆分数组*/

public static byte[][] splitArray(byte[] data, intlen) {int x = data.length /len;int y = data.length %len;int z = 0;if (y != 0) {

z= 1;

}byte[][] arrays = new byte[x +z][];byte[] arr;for (int i = 0; i < x + z; i++) {

arr= new byte[len];if (i == x + z - 1 && y != 0) {

System.arraycopy(data, i* len, arr, 0, y);

}else{

System.arraycopy(data, i* len, arr, 0, len);

}

arrays[i]=arr;

}returnarrays;

}

}

显示代码

5.6:Base64算法

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.meng.study.security;importsun.misc.BASE64Decoder;importsun.misc.BASE64Encoder;

@SuppressWarnings("restriction")public classBASE64Util {/*** base 64 encode

*

*@parambytes

* 待编码的byte[]

*@return编码后的base 64 code*/

public static String base64Encode(byte[] bytes) {return newBASE64Encoder().encode(bytes);

}/*** base 64 decode

*

*@parambase64Code

* 待解码的base 64 code

*@return解码后的byte[]

*@throwsException*/

public static byte[] base64Decode(String base64Code) throwsException {return newBASE64Decoder().decodeBuffer(base64Code);

}

}

显示代码

5.7:测试代码

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.meng.study.security;importjava.security.interfaces.RSAPrivateKey;importjava.security.interfaces.RSAPublicKey;importjava.util.HashMap;/*** 编码工具类 1.将byte[]转为各种进制的字符串 2.base 64 encode 3.base 64 decode

*

*@authoruikoo9

*@version0.0.5.20140601*/

public classEncodeUtilTest {public static void main(String[] args) throwsException {

String msg= "我爱你";

System.out.println("转换前:" +msg);//==Base64==

String base64Str =BASE64Util.base64Encode(msg.getBytes());

System.out.println("Base64转换后:" +base64Str);

System.out.println("Base64解码后:" + newString(BASE64Util.base64Decode(base64Str)));//==Md5==

String md5Base64Str =MD5Util.md5Base64(msg);

System.out.println("Md5后Base编码转换后:" +md5Base64Str);//==Des==

byte[] des =DESUtil.encryptMode(msg.getBytes());

System.out.println("【DES加密后】:" + newString(des));byte[] myMsgArr =DESUtil.decryptMode(des);

System.out.println("【DES解密后】:" + newString(myMsgArr));

String desBase64Str=DESUtil.encryptModeBase64(msg.getBytes());

System.out.println("Des后Base64编码转换后:" +desBase64Str);

System.out.println("Base64解码后Des转换后:" + newString(DESUtil.decryptModeBase64(desBase64Str)));//==Aes==

String aesKey = "123456";

String aesEnStr=AESUtil.aesEncrypt(msg,aesKey);

System.out.println("【AES加密Base64编码后】:" +aesEnStr);

String aesDeStr=AESUtil.aesDecrypt(aesEnStr,aesKey);

System.out.println("【Base64解码AES解密后】:" +aesDeStr);//==Rsa==

HashMap keys =RSAUtil.getKeys();

RSAPublicKey publicKey= (RSAPublicKey) keys.get("public");

RSAPrivateKey privateKey= (RSAPrivateKey) keys.get("private");

RSAPublicKey pubKey=RSAUtil.getPublicKey(publicKey.getModulus().toString(), publicKey.getPublicExponent().toString());

RSAPrivateKey priKey=RSAUtil.getPrivateKey(privateKey.getModulus().toString(), privateKey.getPrivateExponent().toString());

String rsaEnStr=RSAUtil.encryptByPublicKey(msg, pubKey);

System.out.println("【RSA公钥加密后】:" +rsaEnStr);

String rsaDeStr=RSAUtil.decryptByPrivateKey(rsaEnStr, priKey);

System.out.println("【RSA私钥解密后】:" +rsaDeStr);

}

}

显示代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值