JAVA常用加解密算法总结及JAVA实现

本文深入探讨了数据加密、摘要和签名的概念及其实现方式,涵盖了BASE64、MD5、SHA、DES、3DES、AES、RSA等加密算法,解析了不同场景下加密、摘要和签名的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BASE64,MD5,SHA,DES,3DES,AES,RSA

 

BASE64

这其实是一种编解码方法,但是只要我们能够将原文变成肉眼不可识别的内容,其实就是一种加密的方法。

BASE64 的编码都是按字符串长度,以每 3 个 8 bit 的字符为一组,然后针对每组,首先获取每个字符的 ASCII 编码,然后将 ASCII 编码转换成 8 bit 的二进制,得到一组 3*8=24 bit 的字节。然后再将这 24 bit 划分为 4 个 6 bit 的字节,并在每个 6 bit 的字节前面都填两个高位 0,得到 4 个 8 bit 的字节,然后将这 4 个 8 bit 的字节转换成十进制,对照 BASE64 编码表 ,得到对应编码后的字符。

实现:

/**

* Project Name:thread

* File Name:Base64Util.java

* Package Name:enc.dec

* Date:2015年10月21日下午3:49:21

* Copyright (c) 2015, chiwei@chinamobile.com All Rights Reserved.

*

*/


package enc.dec;


import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.OutputStream;


/**

* ClassName:Base64Util <br/>

* Function: TODO ADD FUNCTION. <br/>

* Reason: TODO ADD REASON. <br/>

* Date: 2015年10月21日 下午3:49:21 <br/>

*

* @author chiwei

* @version

* @since JDK 1.6

* @see

*/

public class Base64Util {

private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

.toCharArray();


/**

* data[]进行编码

*

* @param data

* @return

*/

public static String encode(byte[] data) {

int start = 0;

int len = data.length;

StringBuffer buf = new StringBuffer(data.length * 3 / 2);


int end = len - 3;

int i = start;

int n = 0;


while (i <= end) {

int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8)

| (((int) data[i + 2]) & 0x0ff);


buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append(legalChars[(d >> 6) & 63]);

buf.append(legalChars[d & 63]);


i += 3;


if (n++ >= 14) {

n = 0;

buf.append(" ");

}

}


if (i == start + len - 2) {

int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);


buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append(legalChars[(d >> 6) & 63]);

buf.append("=");

} else if (i == start + len - 1) {

int d = (((int) data[i]) & 0x0ff) << 16;


buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append("==");

}


return buf.toString();

}


public static String encode(String data) {

try {

return encode(data.getBytes("UTF-8"));

} catch (Exception e) {

throw new RuntimeException(e);

}

}


private static int decode(char c) {

if (c >= 'A' && c <= 'Z')

return ((int) c) - 65;

else if (c >= 'a' && c <= 'z')

return ((int) c) - 97 + 26;

else if (c >= '0' && c <= '9')

return ((int) c) - 48 + 26 + 26;

else

switch (c) {

case '+':

return 62;

case '/':

return 63;

case '=':

return 0;

default:

throw new RuntimeException("unexpected code: " + c);

}

}


/**

* Decodes the given Base64 encoded String to a new byte array. The byte

* array holding the decoded data is returned.

*/


public static byte[] decode(String s) {


ByteArrayOutputStream bos = new ByteArrayOutputStream();

try {

decode(s, bos);

} catch (IOException e) {

throw new RuntimeException();

}

byte[] decodedBytes = bos.toByteArray();

try {

bos.close();

bos = null;

} catch (IOException ex) {

throw new RuntimeException(ex);

}

return decodedBytes;

}


private static void decode(String s, OutputStream os) throws IOException {

int i = 0;


int len = s.length();


while (true) {

while (i < len && s.charAt(i) <= ' ')

i++;


if (i == len)

break;


int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12)

+ (decode(s.charAt(i + 2)) << 6) + (decode(s.charAt(i + 3)));


os.write((tri >> 16) & 255);

if (s.charAt(i + 2) == '=')

break;

os.write((tri >> 8) & 255);

if (s.charAt(i + 3) == '=')

break;

os.write(tri & 255);


i += 4;

}

}


/**

* data[]进行编码

*

* @param data

* @return

*/

public static String Base64Encoder(byte[] data) {

int start = 0;

int len = data.length;

StringBuffer buf = new StringBuffer(data.length * 3 / 2);


int end = len - 3;

int i = start;

int n = 0;


while (i <= end) {

int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8)

| (((int) data[i + 2]) & 0x0ff);


buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append(legalChars[(d >> 6) & 63]);

buf.append(legalChars[d & 63]);


i += 3;


if (n++ >= 14) {

// 不需要空格

n = 0;

}

}


if (i == start + len - 2) {

int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);


buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append(legalChars[(d >> 6) & 63]);

buf.append("=");

} else if (i == start + len - 1) {

int d = (((int) data[i]) & 0x0ff) << 16;


buf.append(legalChars[(d >> 18) & 63]);

buf.append(legalChars[(d >> 12) & 63]);

buf.append("==");

}


return buf.toString();

}


public static void main(String[] args) {

System.out.println(encode("tree"));

System.out.println(new String(decode(encode("tree"))));

}

}

加解密

 

MD5

Message Digest Algorithm 5
MD5 是用来验证文件的一致性的

/**

* Project Name:thread

* File Name:MD5Util.java

* Package Name:enc.dec

* Date:2015年10月21日下午3:58:02

* Copyright (c) 2015, chiwei@chinamobile.com All Rights Reserved.

*

*/


package enc.dec;


import java.security.MessageDigest;


/**

* ClassName:MD5Util <br/>

* Function: TODO ADD FUNCTION. <br/>

* Reason: TODO ADD REASON. <br/>

* Date: 2015年10月21日 下午3:58:02 <br/>

*

* @author chiwei

* @version

* @since JDK 1.6

* @see

*/

public class MD5Util {


public static String getMD5(String source) {

String s = null;

char hexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',

'E', 'F' };

try {

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

md.update(source.getBytes());// 使用指定的byte数组更新摘要

byte[] hashCalc = md.digest();// 完成哈希计算

char result[] = new char[16 * 2];// MD5结果返回的是32位字符串,每位是16进制表示的

int k = 0;

for (int i = 0; i < 16; i++) {// 循环16次,对每个字节进行操作转换

byte everyByte = hashCalc[i];

result[k++] = hexChar[everyByte >>> 4 & 0xf];// 对每个字节的高4位进行处理,逻辑右移,再相与

result[k++] = hexChar[everyByte & 0xf];// 低4位转换

}

s = new String(result);

} catch (Exception e) {

throw new RuntimeException(e);

}

return s;

}


public static void main(String[] args) {

System.out.println(getMD5("tree"));

}


}

SHA

 

Secure Hash Algorithm

SHA1

SHA-1 有两个特点:
不可以从消息摘要中复原信息
两个不同的消息,不会产生同样的消息摘要

SHA-1 是一种数据加密算法,主要是接收一段明文,然后以一种不可逆的方式将它转换成一段密文,也可以简单的理解为取一串输入码,并把它们转化为长度较短、位数固定的输出序列即散列值的过程。

对应的还有SHA-256,SHA-512,算法更加安全

/**

* Project Name:thread

* File Name:SHAUtil.java

* Package Name:enc.dec

* Date:2015年10月21日下午4:01:50

* Copyright (c) 2015, chiwei@chinamobile.com All Rights Reserved.

*

*/


package enc.dec;


import java.security.MessageDigest;


/**

* ClassName:SHAUtil <br/>

* Function: TODO ADD FUNCTION. <br/>

* Reason: TODO ADD REASON. <br/>

* Date: 2015年10月21日 下午4:01:50 <br/>

*

* @author chiwei

* @version

* @since JDK 1.6

* @see

*/

public class SHAUtil {


/** 算法种类 */

private final static String KEY_SHA1 = "SHA-1";

private final static String KEY_SHA256 = "SHA-256";

private final static String KEY_SHA512 = "SHA-512";


public static String encBySha1(String data) throws Exception {

// 创建具有指定算法名称的信息摘要

MessageDigest sha = MessageDigest.getInstance(KEY_SHA1);

// 使用指定的字节数组对摘要进行最后更新

sha.update(data.getBytes());

// 完成摘要计算

byte[] bytes = sha.digest();

// 将得到的字节数组变成字符串返回

return ByteUtil.byteArrayToHexString(bytes);

}


public static String encBySha256(String data) throws Exception {

// 创建具有指定算法名称的信息摘要

MessageDigest sha = MessageDigest.getInstance(KEY_SHA256);

// 使用指定的字节数组对摘要进行最后更新

sha.update(data.getBytes());

// 完成摘要计算

byte[] bytes = sha.digest();

// 将得到的字节数组变成字符串返回

return ByteUtil.byteArrayToHexString(bytes);

}


public static String encBySha512(String data) throws Exception {

// 创建具有指定算法名称的信息摘要

MessageDigest sha = MessageDigest.getInstance(KEY_SHA512);

// 使用指定的字节数组对摘要进行最后更新

sha.update(data.getBytes());

// 完成摘要计算

byte[] bytes = sha.digest();

// 将得到的字节数组变成字符串返回

return ByteUtil.byteArrayToHexString(bytes);

}


public static void main(String[] args) throws Exception {

String key = "123";

System.out.println(encBySha1(key));

System.out.println(encBySha256(key));

System.out.println(encBySha512(key));

}


}

DES,3DES,AES对称加密

 

DES 算法把 64 位的明文输入块变为 64 位的密文输出块,它所使用的密钥也是 64 位,其算法主要分为两步:

初始置换
其功能是把输入的 64 位数据块按位重新组合,并把输出分为 L0、R0 两部分,每部分各长 32 位,其置换规则为将输入的第 58 位换到第一位,第 50 位换到第 2 位 …… 依此类推,最后一位是原来的第 7 位。L0、R0 则是换位输出后的两部分,L0 是输出的左 32 位,R0 是右 32 位,例:设置换前的输入值为 D1 D2 D3 …… D64,则经过初始置换后的结果为:L0 = D58 D50 …… D8;R0 = D57 D49 …… D7。

逆置换
经过 16 次迭代运算后,得到 L16、R16,将此作为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即得到密文输出。

3DES,也就是“Triple DES”,中文名“三重数据加密算法”,它相当于是对每个数据块应用三次 DES 加密算法。由于计算机运算能力的增强,原版 DES 密码的密钥长度变得容易被暴力破解;3DES 即是设计用来提供一种相对简单的方法,即通过增加 DES 的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

AES,全称为“Advanced Encryption Standard”,中文名“高级加密标准”,在密码学中又称 Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。AES 加密算法作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点。AES 设计有三个密钥长度:128,192,256 位。相对而言,AES 的 128 密钥比 DES 的 56 密钥强了 1021 倍。

/**

* Project Name:thread

* File Name:DESUtil.java

* Package Name:enc.dec

* Date:2015年10月21日下午4:17:14

* Copyright (c) 2015, chiwei@chinamobile.com All Rights Reserved.

*

*/


package enc.dec;


import java.security.SecureRandom;


import javax.crypto.Cipher;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.DESKeySpec;

import javax.crypto.spec.SecretKeySpec;


/**

* ClassName:DESUtil <br/>

* Function: TODO ADD FUNCTION. <br/>

* Reason: TODO ADD REASON. <br/>

* Date: 2015年10月21日 下午4:17:14 <br/>

*

* @author chiwei

* @version

* @since JDK 1.6

* @see

*/

public class DESUtil {

private final static String KEY_DES = "DES";

private static final String KEY_3_DES = "DESede";

private final static String KEY_AES = "AES"; // 测试

//长度8字节

private final static String DES_KEY = "12345678";

//长度24字节

private final static String DES_3_KEY = "213456781234567812345678";

//长度16,24,32字节

private final static String AES_KEY = "1234567812345678";


private static byte[] decByDes(byte[] data) throws Exception {

// DES算法要求有一个可信任的随机数源

SecureRandom random = new SecureRandom();

DESKeySpec desKey = new DESKeySpec(DES_KEY.getBytes());

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);

SecretKey securekey = keyFactory.generateSecret(desKey);

Cipher cipher = Cipher.getInstance(KEY_DES);

cipher.init(Cipher.DECRYPT_MODE, securekey, random);

return cipher.doFinal(data);

}


private static byte[] encByDes(byte[] data) throws Exception {

DESKeySpec desKey = new DESKeySpec(DES_KEY.getBytes());

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);

SecretKey securekey = keyFactory.generateSecret(desKey);

Cipher cipher = Cipher.getInstance(KEY_DES);

cipher.init(Cipher.ENCRYPT_MODE, securekey);

return cipher.doFinal(data);

}


private static byte[] decBy3Des(byte[] data) throws Exception {

SecureRandom random = new SecureRandom();

SecretKey deskey = new SecretKeySpec(DES_3_KEY.getBytes(), KEY_3_DES);

Cipher cipher = Cipher.getInstance(KEY_3_DES);

cipher.init(Cipher.DECRYPT_MODE, deskey, random);

return cipher.doFinal(data);

}


private static byte[] encBy3Des(byte[] data) throws Exception {

SecureRandom random = new SecureRandom();

SecretKey deskey = new SecretKeySpec(DES_3_KEY.getBytes(), KEY_3_DES);

Cipher cipher = Cipher.getInstance(KEY_3_DES);

cipher.init(Cipher.ENCRYPT_MODE, deskey, random);

return cipher.doFinal(data);

}


private static byte[] decByAes(byte[] data) throws Exception {

SecretKey deskey = new SecretKeySpec(AES_KEY.getBytes(), KEY_AES);

Cipher cipher = Cipher.getInstance(KEY_AES);

cipher.init(Cipher.DECRYPT_MODE, deskey);

return cipher.doFinal(data);

}


private static byte[] encByAes(byte[] data) throws Exception {

SecretKey deskey = new SecretKeySpec(AES_KEY.getBytes(), KEY_AES);

Cipher cipher = Cipher.getInstance(KEY_AES);

cipher.init(Cipher.ENCRYPT_MODE, deskey);

return cipher.doFinal(data);

}


public static void main(String[] args) throws Exception {

System.out.println("DES密钥:\n" + DES_KEY);

System.out.println("DES密钥字节长度:\n" + DES_KEY.getBytes().length);

String word = "123";

System.out.println("原文:" + word);

System.out.println("=============DES=============");

byte b[] = encByDes(word.getBytes());

String encWord = new String(b);

System.out.println("加密后:" + encWord);

System.out.println("解密后:" + new String(decByDes(b)));

System.out.println("=============3DES=============");

System.out.println("3DES密钥:" + DES_3_KEY);

System.out.println("3DES密钥字节长度:" + DES_3_KEY.getBytes().length);

b = encBy3Des(word.getBytes());

encWord = new String(b);

System.out.println("加密后:" + encWord);

System.out.println("解密后:" + new String(decBy3Des(b)));

System.out.println("=============AES=============");

System.out.println("AES密钥:" + AES_KEY);

System.out.println("AES密钥字节长度:" + AES_KEY.getBytes().length);

b = encByAes(word.getBytes());

encWord = new String(b);

System.out.println("加密后:" + encWord);

System.out.println("解密后:" + new String(decByAes(b)));

}


}

RSA非对称加密

/**

* Project Name:thread

* File Name:RSAUtil.java

* Package Name:enc.dec

* Date:2015年10月22日上午9:21:01

* Copyright (c) 2015, chiwei@chinamobile.com All Rights Reserved.

*

*/


package enc.dec;


import java.io.ByteArrayOutputStream;

import java.security.Key;

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.Signature;

import java.security.interfaces.RSAPrivateKey;

import java.security.interfaces.RSAPublicKey;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

import java.util.HashMap;

import java.util.Map;


import javax.crypto.Cipher;


import com.alibaba.fastjson.JSONObject;


/**

* ClassName:RSAUtil <br/>

* Function: TODO ADD FUNCTION. <br/>

* Reason: TODO ADD REASON. <br/>

* Date: 2015年10月22日 上午9:21:01 <br/>

*

* @author chiwei

* @version

* @since JDK 1.6

* @see

*/

public class RSAUtil {


/**

* 加密算法RSA

*/

public static final String KEY_ALGORITHM = "RSA";


/**

* 签名算法

*/

public static final String SIGNATURE_ALGORITHM = "MD5withRSA";


/**

* 获取公钥的key

*/

private static final String PUBLIC_KEY = "RSAPublicKey";


private static final int keyLen = 512;// 密钥长度


/**

* 获取私钥的key

*/

private static final String PRIVATE_KEY = "RSAPrivateKey";


/**

* RSA最大加密明文大小

*/

private static final int MAX_ENCRYPT_BLOCK = keyLen / 8 - 11;


/**

* RSA最大解密密文大小

*/

private static final int MAX_DECRYPT_BLOCK = keyLen / 8;


/**

*

* genKeyPair:(). <br/>


* 生成公司钥对,返回的是经过BASE64编码的密钥

* @author chiwei

* @return

* @throws Exception

* @since JDK 1.6

*/

public static Map<String, Object> genKeyPair() throws Exception {

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);

keyPairGen.initialize(keyLen);

KeyPair keyPair = keyPairGen.generateKeyPair();

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

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

Map<String, Object> keyMap = new HashMap<String, Object>(2);

keyMap.put(PUBLIC_KEY, publicKey);

keyMap.put(PRIVATE_KEY, privateKey);

return keyMap;

}


/**

*

* sign:(). <br/>


* 用私钥进行签名,返回BASE64编码的内容

* @author chiwei

* @param data

* @param privateKey

* @return

* @throws Exception

* @since JDK 1.6

*/

public static String sign(byte[] data, String privateKey) throws Exception {

byte[] keyBytes = Base64Util.decode(privateKey);

PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);

Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

signature.initSign(privateK);

signature.update(data);

return Base64Util.encode(signature.sign());

}


/**

*

* verify:(). <br/>


* 用公钥对签名进行验证

* @author chiwei

* @param data

* @param publicKey

* @param sign

* @return

* @throws Exception

* @since JDK 1.6

*/

public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {

byte[] keyBytes = Base64Util.decode(publicKey);

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

PublicKey publicK = keyFactory.generatePublic(keySpec);

Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

signature.initVerify(publicK);

signature.update(data);

return signature.verify(Base64Util.decode(sign));

}


/**

*

* decryptByPrivateKey:(). <br/>


* 私钥解密

* @author chiwei

* @param encryptedData

* @param privateKey

* @return

* @throws Exception

* @since JDK 1.6

*/

public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)

throws Exception {

byte[] keyBytes = Base64Util.decode(privateKey);

PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.DECRYPT_MODE, privateK);

int inputLen = encryptedData.length;

ByteArrayOutputStream out = new ByteArrayOutputStream();

int offSet = 0;

byte[] cache;

int i = 0;

// 对数据分段解密

while (inputLen - offSet > 0) {

if (inputLen - offSet > MAX_DECRYPT_BLOCK) {

cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);

} else {

cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);

}

out.write(cache, 0, cache.length);

i++;

offSet = i * MAX_DECRYPT_BLOCK;

}

byte[] decryptedData = out.toByteArray();

out.close();

return decryptedData;

}


/**

*

* decryptByPublicKey:(). <br/>


* 公钥解密

* @author chiwei

* @param encryptedData

* @param publicKey

* @return

* @throws Exception

* @since JDK 1.6

*/

public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)

throws Exception {

byte[] keyBytes = Base64Util.decode(publicKey);

X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);

KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

Key publicK = keyFactory.generatePublic(x509KeySpec);

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.DECRYPT_MODE, publicK);

int inputLen = encryptedData.length;

ByteArrayOutputStream out = new ByteArrayOutputStream();

int offSet = 0;

byte[] cache;

int i = 0;

// 对数据分段解密

while (inputLen - offSet > 0) {

if (inputLen - offSet > MAX_DECRYPT_BLOCK) {

cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);

} else {

cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);

}

out.write(cache, 0, cache.length);

i++;

offSet = i * MAX_DECRYPT_BLOCK;

}

byte[] decryptedData = out.toByteArray();

out.close();

return decryptedData;

}


/**

*

* encryptByPublicKey:(). <br/>


* 公钥加密

* @author chiwei

* @param data

* @param publicKey

* @return

* @throws Exception

* @since JDK 1.6

*/

public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {

byte[] keyBytes = Base64Util.decode(publicKey);

X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);

KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

Key publicK = keyFactory.generatePublic(x509KeySpec);

// 对数据加密

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.ENCRYPT_MODE, publicK);

int inputLen = data.length;

ByteArrayOutputStream out = new ByteArrayOutputStream();

int offSet = 0;

byte[] cache;

int i = 0;

// 对数据分段加密

while (inputLen - offSet > 0) {

if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {

cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);

} else {

cache = cipher.doFinal(data, offSet, inputLen - offSet);

}

out.write(cache, 0, cache.length);

i++;

offSet = i * MAX_ENCRYPT_BLOCK;

}

byte[] encryptedData = out.toByteArray();

out.close();

return encryptedData;

}


/**

*

* encryptByPrivateKey:(). <br/>


* 私钥加密

* @author chiwei

* @param data

* @param privateKey

* @return

* @throws Exception

* @since JDK 1.6

*/

public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {

byte[] keyBytes = Base64Util.decode(privateKey);

PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);

Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());

cipher.init(Cipher.ENCRYPT_MODE, privateK);

int inputLen = data.length;

ByteArrayOutputStream out = new ByteArrayOutputStream();

int offSet = 0;

byte[] cache;

int i = 0;

// 对数据分段加密

while (inputLen - offSet > 0) {

if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {

cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);

} else {

cache = cipher.doFinal(data, offSet, inputLen - offSet);

}

out.write(cache, 0, cache.length);

i++;

offSet = i * MAX_ENCRYPT_BLOCK;

}

byte[] encryptedData = out.toByteArray();

out.close();

return encryptedData;

}


/**

*

* getPrivateKey:(). <br/>


* 获取BASE64编码的私钥

* @author chiwei

* @param keyMap

* @return

* @throws Exception

* @since JDK 1.6

*/

public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {

Key key = (Key) keyMap.get(PRIVATE_KEY);

return Base64Util.encode(key.getEncoded());

}


/**

*

* getPublicKey:(). <br/>


* 获取BASE64编码的公钥

* @author chiwei

* @param keyMap

* @return

* @throws Exception

* @since JDK 1.6

*/

public static String getPublicKey(Map<String, Object> keyMap) throws Exception {

Key key = (Key) keyMap.get(PUBLIC_KEY);

return Base64Util.encode(key.getEncoded());

}


public static void main(String args[]) {

JSONObject json = new JSONObject();

json.put("deviceId", "1");

json.put("clientVersion", "2");

json.put("platform", "1");

JSONObject position = new JSONObject();

position.put("location_latitude_key", "10.98");

position.put("location_longtitude_key", "110.98");

json.put("position", position);

json.put("city", "杭州市");

json.put("locatedAddress", "");

json.put("romVersion", "1");

json.put("commandId", 0x125);

json.put("userId", 10049);

json.put("orderId", 10053);

System.out.println(json);

String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIc7AHO19/BdTKI18QDeqOxHCNHI w8+2C15kvE5h+kYoQxCq3IdVDsJJKFJSAtfOe7WHgLUDOpAZaHcUnpW7HpUC AwEAAQ==";// "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZozfHvyz7LZIAo7BPX2HE DHc4CZR9UIwPC/omfaJ62f8l2na+YRKQHBE220+RQfqupVMKmy7QYo+hAjs4 MqCgCedqyWBwHhrhTbQp5FuZ/xaqFCuz/ntyYzz7NrYoD3ijtwBXUrx6kTJf xtkB/Nhd317JHuzxPR9bNUj3K5pLfwIDAQAB";

String privateKey = "MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAhzsAc7X38F1M ojXxAN6o7EcI0cjDz7YLXmS8TmH6RihDEKrch1UOwkkoUlIC1857tYeAtQM6 kBlodxSelbselQIDAQABAkBwhC4XGMPoMajumpUhFSJWHbB/5FzQOXbyHjzz tt/neKONwuB25QJ+DehwtKGnjDtcrSlUbNYIc0L95eKPGvJBAiEA39pNrReU WThfcQkz1TEmL+Pqh09Uf5KdkUJFRn3rEsUCIQCapplvyKoWiC2//J8NXUds 1SyNv5+vsXlwhtPqJsNZkQIgEEIy0hecVr6ZcARTF3DybRgIuLsyT/G+MAa4 MV6D7GECICocr6+G3vofvwWGjvEes3JpYiZ/Rcab90uzC0W5pHxhAiAvPq16 AvszXkXVZXgvEHoyG2qvbj0I7VkCsHI8C0E1xQ==";// "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJmjN8e/LPst kgCjsE9fYcQMdzgJlH1QjA8L+iZ9onrZ/yXadr5hEpAcETbbT5FB+q6lUwqb LtBij6ECOzgyoKAJ52rJYHAeGuFNtCnkW5n/FqoUK7P+e3JjPPs2tigPeKO3 AFdSvHqRMl/G2QH82F3fXske7PE9H1s1SPcrmkt/AgMBAAECf0sEZzghINWE asXlJzGaYSJY891o0BhgPAMc1gf1UGCsEOlqwpAy1d2H1t/yNee3T6/3CZUk MLePaJI1hLTsA4FcGzEWKUy7Hn2CqIjUzkJdax6CYXlK0hcoI47fiCr7Wtcx U/6P1uN+shA5ICHF0nZYJ2vEO1Vw/xMVGnLIRykCQQDwHJ0yOJZde7nZxo56 xka2C1tfMNjziXkdFH6EGfaiT0iJkJ+Kd11m0LukUxLPo5U1O63ZYkWOtFen wL2FmJTzAkEAo83FAO23KDZAyaPJg4K1PWqScF8+BDK51QxmJR0iCcl2umck jTfnO53wE8zjGNH/nqKQK6D+RUs8vEWaI37CRQJBAKKEW4mQb4XappJWKD3F UjsJONEXOOCtncInCvLSt/JoA0rJDpMj854Rjc/NQqAzslwThrnqH/ZU7jdm 52AzRC0CQB62djm2WKExivRDwYTm/RSG5u4q7XXcDPvlV0GeNMOhAqHwtOnF kZWcB2evAuWkeklEMcP8a7CSatDiPARrwAECQQC0SMsT/xukGzOh4SkHEirN bdFwdLdFeJf+8O3Tsf7iYlTNhnGEgTLQeaf3xOoivGtJEXZwT7vJWtiTUXRW 8P1v";

try {

// Map key = genKeyPair();

// publicKey = getPublicKey(key);

// privateKey = getPrivateKey(key);

System.out.println("公钥-->" + publicKey);

System.out.println("私钥-->" + privateKey);

System.out.println("待加密的字符串:" + json);

byte[] enBy = encryptByPublicKey(json.toJSONString().getBytes(), publicKey);

String enStr = new String(enBy, "UTF-8");

System.out.println("加密后:" + enStr);

String enEncode = Base64Util.encode(enBy);

System.out.println("加密后编码内容:" + enEncode);

byte[] deBy = decryptByPrivateKey(Base64Util.decode(enEncode), privateKey);

System.out.println("解密后:" + new String(deBy));

System.out.println("解密后编码内容:" + Base64Util.encode(deBy));

String sign = sign(enBy,privateKey);

System.out.println("签名:"+sign);

System.out.println("对签名验证:"+verify(enBy, publicKey, sign));

System.out.println("BASE64编码密文摘要:"+MD5Util.getMD5(enEncode));

} catch (Exception e) {

e.printStackTrace();

}

}

}

数据加密:

为了保证数据的安全性,不会泄露数据的真是内容

数据摘要:

为了确保数据中途没有被篡改过,数据的内容时完整的正确的

数据签名:

为了保证数据是对方过来的,而不是从别的地方来的

 

在真实的互联网应用中,加密场景非常重要

1、对数据加密

2、对密文生成摘要

3、对摘要进行签名

4、将密文和签名一起发送

这样就保证了数据的安全性

这里还有一个唯一的漏洞就是接收方的公钥被人替换了,所以就出现了证书认证中心

确保公钥的安全性,在发送数据的时候加上数字证书。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值