[转帖]数据加密之加密算法
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
:数据加密之加密算法![]() encrypt-decrypt1 密码学基本概念1.1 古典密码学1.2 近代密码学1.3 现代密码学2 凯撒加密2.1 凯撒加密解密的实现public class KaiSaUtil {
// 加密
public static String encryptKaiser(String original, Integer key) {
// 1、将输入的字符串转换成字符数组
char[] chars = original.toCharArray();
StringBuilder sb = new StringBuilder();
for (char aChar : chars) {
// 2、获取字符的ascii编码
int asciiCode = aChar;
// 3、偏移数据
asciiCode += key;
// 4、将偏移后的数据转为字符
char result = (char) asciiCode;
// 5、拼接数据
sb.append(result);
}
return sb.toString();
}
// 解密
public static String decryptKaiser(String encryptedData, int key) {
// 1、将密文转换成字符数组
char[] chars = encryptedData.toCharArray();
StringBuilder sb = new StringBuilder();
for (char aChar : chars) {
// 2、获取字符的ascii编码
int asciiCode = aChar;
// 3、偏移数据
asciiCode -= key;
// 4、将偏移后的数据转为字符
char result = (char) asciiCode;
// 5、拼接数据
sb.append(result);
}
return sb.toString();
}}123456789101112131415161718192021222324252627282930313233343536
public class KaiSaDemo {
public static void main(String[] args) {
String input = "welcome";
Integer key = 3;
System.out.println("加密前:" + input);
String encryptKaiser = KaiSaUtil.encryptKaiser(input, key);
System.out.println("加密后:" + encryptKaiser);
String decryptKaiser = KaiSaUtil.decryptKaiser(encryptKaiser, key);
System.out.println("解密后:" + decryptKaiser);
}}测试结果:
加密前:welcome
加密后:zhofrph
解密后:welcome1234567891011121314152.2 使用频度分析法破解凯撒加密public static void main(String[] args) throws Exception {
//测试1,统计字符个数
//printCharCount("article.txt");
//加密文件
int key = 3;
encryptFile("article.txt", "article_en.txt", key);
//读取加密后的文件
// String artile = Util.file2String("article_en.txt");
//解密(会生成多个备选文件)
// decryptCaesarCode(artile, "article_de.txt");
}12345678910111213
public static void main(String[] args) throws Exception {
//测试1,统计字符个数
printCharCount("article_en.txt");
//加密文件
int key = 3;
//encryptFile("article.txt", "article_en.txt", key);
//读取加密后的文件
// String artile = Util.file2String("article_en.txt");
//解密(会生成多个备选文件)
// decryptCaesarCode(artile, "article_de.txt");
}12345678910111213
public class FrequencyUtil {
public static void print(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
sb.append(bytes[i]).append(" ");
}
System.out.println(sb);
}
public static String file2String(String path) throws IOException {
FileReader reader = new FileReader(new File(path));
char[] buffer = new char[1024];
int len = -1;
StringBuffer sb = new StringBuffer();
while ((len = reader.read(buffer)) != -1) {
sb.append(buffer, 0, len);
}
return sb.toString();
}
public static void string2File(String data, String path) {
FileWriter writer = null;
try {
writer = new FileWriter(new File(path));
writer.write(data);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String inputStream2String(InputStream in) throws IOException {
int len = -1;
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len = in.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
baos.close();
return baos.toString("UTF-8");
}}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
public class FrequencyAnalysis {
//英文里出现次数最多的字符
private static final char MAGIC_CHAR = 'e';
//破解生成的最大文件数
private static final int DE_MAX_FILE = 4;
public static void main(String[] args) throws Exception {
//测试1,统计字符个数// printCharCount("D:\\IDEA\\encrypt-decrypt\\src\\article.txt");
//加密文件
int key = 3;// encryptFile("D:\\\\IDEA\\\\encrypt-decrypt\\\\src\\\\article.txt", "D:\\IDEA\\encrypt-decrypt\\src\\article_en.txt", key);
//读取加密后的文件
String artile = FrequencyUtil.file2String("D:\\IDEA\\encrypt-decrypt\\src\\article_en.txt");
//解密(会生成多个备选文件)
decryptCaesarCode(artile, "article_de.txt");
}
public static void printCharCount(String path) throws IOException {
String data = FrequencyUtil.file2String(path);
List<Entry<Character, Integer>> mapList = getMaxCountChar(data);
for (Entry<Character, Integer> entry : mapList) {
//输出前几位的统计信息
System.out.println("字符'" + entry.getKey() + "'出现" + entry.getValue() + "次");
}
}
public static void encryptFile(String srcFile, String destFile, int key) throws IOException {
String artile = FrequencyUtil.file2String(srcFile);
//加密文件
String encryptData = KaiSaUtil.encryptKaiser(artile, key);
//保存加密后的文件
FrequencyUtil.string2File(encryptData, destFile);
}
/**
* 破解凯撒密码
*
* @param input 数据源
* @return 返回解密后的数据
*/
public static void decryptCaesarCode(String input, String destPath) {
int deCount = 0;//当前解密生成的备选文件数
//获取出现频率最高的字符信息(出现次数越多越靠前)
List<Entry<Character, Integer>> mapList = getMaxCountChar(input);
for (Entry<Character, Integer> entry : mapList) {
//限制解密文件备选数
if (deCount >= DE_MAX_FILE) {
break;
}
//输出前几位的统计信息
System.out.println("字符'" + entry.getKey() + "'出现" + entry.getValue() + "次");
++deCount;
//出现次数最高的字符跟MAGIC_CHAR的偏移量即为秘钥
int key = entry.getKey() - MAGIC_CHAR;
System.out.println("猜测key = " + key + ", 解密生成第" + deCount + "个备选文件" + "\n");
String decrypt = KaiSaUtil.decryptKaiser(input, key);
String fileName = "de_" + deCount + destPath;
FrequencyUtil.string2File(decrypt, fileName);
}
}
//统计String里出现最多的字符
public static List<Entry<Character, Integer>> getMaxCountChar(String data) {
Map<Character, Integer> map = new HashMap<Character, Integer>();
char[] array = data.toCharArray();
for (char c : array) {
if (!map.containsKey(c)) {
map.put(c, 1);
} else {
Integer count = map.get(c);
map.put(c, count + 1);
}
}
//输出统计信息
for (Entry<Character, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + "出现" + entry.getValue() + "次");
}
//获取获取最大值
int maxCount = 0;
for (Entry<Character, Integer> entry : map.entrySet()) {
//不统计空格
if (/*entry.getKey() != ' ' && */entry.getValue() > maxCount) {
maxCount = entry.getValue();
}
}
//map转换成list便于排序
List<Entry<Character, Integer>> mapList = new ArrayList<Map.Entry<Character, Integer>>(map.entrySet());
//根据字符出现次数排序
Collections.sort(mapList, new Comparator<Entry<Character, Integer>>() {
public int compare(Entry<Character, Integer> o1,
Entry<Character, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
return mapList;
}}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051063 常见加密方式3.1 对称加密3.2 DES加密解密public class DesAesDemo {
public static void main(String[] args) throws Exception {
// 原文
String input = "hello";
// des加密必须是8位
String key = "12345678";
// 算法
String algorithm = "DES";
// 加密类型
String transformation = "DES";
// Cipher:密码,获取加密对象
// transformation:参数表示使用什么类型加密
Cipher cipher = Cipher.getInstance(transformation);
// 指定秘钥规则
// 第一个参数表示:密钥,key的字节数组
// 第二个参数表示:算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// 对加密进行初始化
// 第一个参数:表示模式,有加密模式和解密模式
// 第二个参数:表示秘钥规则
cipher.init(Cipher.ENCRYPT_MODE, sks);
// 进行加密
byte[] bytes = cipher.doFinal(input.getBytes());
// 打印字节,因为ascii码有负数,解析不出来,所以乱码
for (byte b : bytes) {
System.out.println(b);
}
// 打印密文
System.out.println(new String(bytes));
}}测试结果: -70
22
-58
-96
37
113
37
-81
�Ơ%q%�1234567891011121314151617181920212223242526272829303132333435363738394041
转码代码: String encode = Base64.encode(bytes); 测试结果: base64转码前:�i,6�M base64转码后:2GksNrsVEk0=123456 // 解密方法:
public static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
// 1,获取Cipher对象
Cipher cipher = Cipher.getInstance(transformation);
// 指定密钥规则
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
cipher.init(Cipher.DECRYPT_MODE, sks);
// 3. 解密,上面使用的base64编码,下面直接用密文
byte[] bytes = cipher.doFinal(Base64.decode(input));
// 因为是明文,所以直接返回
return new String(bytes);
}1234567891011123.3 base64Base64是网络上最常见的用于传输8Bit字节码的可读性编码算法之一 可读性编码算法不是为了保护数据的安全性,而是为了可读性 可读性编码不改变信息内容,只改变信息内容的表现形式 所谓Base64,即是说在编码过程中使用了64种字符:大写A到Z、小写a到z、数字0到9、“+”和“/” Base58是Bitcoin(比特币)中使用的一种编码方式,主要用于产生Bitcoin的钱包地址 相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"i",以及"+"和"/"符号123456 public class TestBase64 {
public static void main(String[] args) {
// 1:MQ== 表示一个字节,不够三个字节,所以需要后面通过 == 号补齐
System.out.println(Base64.encode("1".getBytes()));// System.out.println(Base64.encode("12".getBytes()));// System.out.println(Base64.encode("123".getBytes()));// // 你好:中文占6个字节,6 * 8 = 48 ,刚刚好被整除,所以没有等号// System.out.println(Base64.encode("你好".getBytes()));
}}测试结果:
MQ==
MTI=
MTIZ1234567891011121314153.4 AES加密解密public class AESUtil {
// 加密方法
public static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
// 获取加密对象
Cipher cipher = Cipher.getInstance(transformation);
// 创建加密规则
// 第一个参数key的字节
// 第二个参数表示加密算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// ENCRYPT_MODE:加密模式
// DECRYPT_MODE: 解密模式
// 初始化加密模式和算法
cipher.init(Cipher.ENCRYPT_MODE,sks);
// 加密
byte[] bytes = cipher.doFinal(input.getBytes());
// 输出加密后的数据
String encode = Base64.encode(bytes);
return encode;
}
// 解密方法:
public static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
// 1,获取Cipher对象
Cipher cipher = Cipher.getInstance(transformation);
// 指定密钥规则
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
cipher.init(Cipher.DECRYPT_MODE, sks);
// 3. 解密,上面使用的base64编码,下面直接用密文
byte[] bytes = cipher.doFinal(Base64.decode(input));
// 因为是明文,所以直接返回
return new String(bytes);
}}1234567891011121314151617181920212223242526272829303132333435
public class AESDemo {
public static void main(String[] args) throws Exception {
String input = "原文";
// DES加密算法,key的大小必须是8个字节
String key = "1234567812345678";
String transformation = "AES";
// 指定获取密钥的算法
String algorithm = "AES";
String encryptDES = AESUtil.encryptDES(input, key, transformation, algorithm);
System.out.println("加密:" + encryptDES);
String s = AESUtil.decryptDES(encryptDES, key, transformation, algorithm);
System.out.println("解密:" + s);
}}测试结果:
加密:TUuxDy0h/Rx1KwhMFXEnog==
解密:原文1234567891011121314151617
3.5 toString()与new String ()用法区别4 加密模式5 填充模式AES/CBC/NoPadding (128)AES/CBC/PKCS5Padding (128)AES/ECB/NoPadding (128)AES/ECB/PKCS5Padding (128)DES/CBC/NoPadding (56)DES/CBC/PKCS5Padding (56)DES/ECB/NoPadding (56)DES/ECB/PKCS5Padding (56)DESede/CBC/NoPadding (168)DESede/CBC/PKCS5Padding (168)DESede/ECB/NoPadding (168)DESede/ECB/PKCS5Padding (168)RSA/ECB/PKCS1Padding (1024, 2048)RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)123456789101112131415 6 消息摘要- MD5- SHA1- SHA256- SHA5121234 bd465ea30ee7e0a66ed67e86d45a53aa5aba0c8d190934e7dfa58294a21ada7b967877d848e1836a19bf01437cab64f275ac827d81b3f3253eb961b60361a045 *apache-tomcat-10.0.2.exe1 // 消息摘要算法,为了防止篡改public class DigestDemo1 {
public static void main(String[] args) throws NoSuchAlgorithmException {
// 原文
String input = "aa";
// 算法
String algorithm = "MD5";
// 获取数字摘要对象
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 获取消息数字摘要的字节数组
byte[] digest = messageDigest.digest(input.getBytes());
System.out.println(new String(digest));
// 结合base64解决转码
System.out.println(Base64.encode(digest));
}}测试结果:
A$�
�5�o$� zI
转码后:QSS8CpM1wn8IbyS6IHpJEg==123456789101112131415161718192021
// 4124bc0a9335c27f086f24ba207a4912 md5 在线校验 // QSS8CpM1wn8IbyS6IHpJEg== 消息摘要使用的是16进制12 // 消息摘要算法,为了防止篡改public class DigestDemo1 {
public static void main(String[] args) throws NoSuchAlgorithmException {
// 原文
String input = "aa";
// 算法
String algorithm = "MD5";
// 获取数字摘要对象
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 获取消息数字摘要的字节数组
byte[] digest = messageDigest.digest(input.getBytes());
// 创建对象用来拼接
StringBuilder sb = new StringBuilder();
// 对密文进行迭代
for (byte b : digest) {
// 转成 16进制
String s = Integer.toHexString(b & 0xff);// System.out.println(s);
if (s.length() == 1){
// 如果生成的字符只有一个,前面补0
s = "0"+s;
}
sb.append(s);
}
System.out.println(sb.toString());
}}12345678910111213141516171819202122232425262728
public class DigestDemo12 {
public static void main(String[] args) throws Exception {
// 原文
String input = "aa";
// 算法
String algorithm = "MD5";
// 获取数字摘要对象
String md5 = getDigest(input, "MD5");
System.out.println(md5);
String sha1 = getDigest(input, "SHA-1");
System.out.println(sha1);
String sha256 = getDigest(input, "SHA-256");
System.out.println(sha256);
String sha512 = getDigest(input, "SHA-512");
System.out.println(sha512);
}
private static String toHex(byte[] digest) throws Exception {// System.out.println(new String(digest));
// base64编码// System.out.println(Base64.encode(digest));
// 创建对象用来拼接
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
// 转成 16进制
String s = Integer.toHexString(b & 0xff);
if (s.length() == 1) {
// 如果生成的字符只有一个,前面补0
s = "0" + s;
}
sb.append(s);
}
System.out.println("16进制数据的长度:" + sb.toString().getBytes().length);
return sb.toString();
}
private static String getDigest(String input, String algorithm) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 消息数字摘要
byte[] digest = messageDigest.digest(input.getBytes());
System.out.println("密文的字节长度:" + digest.length);
return toHex(digest);
}}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
public class DigestDemo {
public static void main(String[] args) throws Exception {
String input = "aa";
String algorithm = "MD5";
// sha1 可以实现秒传功能
String sha1 = getDigestFile("D:\\apache-tomcat-9.0.41.zip", "SHA-1");
System.out.println(sha1);
String sha512 = getDigestFile("D:\\apache-tomcat-9.0.41.zip", "SHA-512");
System.out.println(sha512);
String md5 = getDigest("aa", "MD5");
System.out.println(md5);
String md51 = getDigest("aa ", "MD5");
System.out.println(md51);
}
private static String getDigestFile(String filePath, String algorithm) throws Exception {
FileInputStream fis = new FileInputStream(filePath);
int len;
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
// 获取消息摘要对象
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
// 获取消息摘要
byte[] digest = messageDigest.digest(baos.toByteArray());
System.out.println("密文的字节长度:" + digest.length);
return toHex(digest);
}
private static String getDigest(String input, String algorithm) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
byte[] digest = messageDigest.digest(input.getBytes());
System.out.println("密文的字节长度:" + digest.length);
return toHex(digest);
}
private static String toHex(byte[] digest) {
// System.out.println(new String(digest));
// 消息摘要进行表示的时候,是用16进制进行表示
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
// 转成16进制
String s = Integer.toHexString(b & 0xff);
// 保持数据的完整性,前面不够的用0补齐
if (s.length() == 1) {
s = "0" + s;
}
sb.append(s);
}
System.out.println("16进制数据的长度:" + sb.toString().getBytes().length);
return sb.toString();
}}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
7 非对称加密7.1 生成公钥和私钥public class RSAdemo {
public static void main(String[] args) throws Exception {
// 加密算法
String algorithm = "RSA";
// 创建密钥对生成器对象
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 生成私钥
PrivateKey privateKey = keyPair.getPrivate();
// 生成公钥
PublicKey publicKey = keyPair.getPublic();
// 获取私钥字节数组
byte[] privateKeyEncoded = privateKey.getEncoded();
// 获取公钥字节数组
byte[] publicKeyEncoded = publicKey.getEncoded();
// 对公私钥进行base64编码
String privateKeyString = Base64.encode(privateKeyEncoded);
String publicKeyString = Base64.encode(publicKeyEncoded);
// 打印私钥
System.out.println(privateKeyString);
// 打印公钥
System.out.println(publicKeyString);
}}123456789101112131415161718192021222324257.2 私钥加密// 私钥加密public class RSAdemo {
public static void main(String[] args) throws Exception {
String input = "hello";
// 加密算法
String algorithm = "RSA";
// 创建密钥对生成器对象
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 生成私钥
PrivateKey privateKey = keyPair.getPrivate();
// 生成公钥
PublicKey publicKey = keyPair.getPublic();
// 获取私钥字节数组
byte[] privateKeyEncoded = privateKey.getEncoded();
// 获取公钥字节数组
byte[] publicKeyEncoded = publicKey.getEncoded();
// 对公私钥进行base64编码
String privateKeyString = Base64.encode(privateKeyEncoded);
String publicKeyString = Base64.encode(publicKeyEncoded);
// 创建加密对象
// 参数表示加密算法
Cipher cipher = Cipher.getInstance(algorithm);
// 初始化加密
// 第一个参数:加密的模式
// 第二个参数:使用私钥进行加密
cipher.init(Cipher.ENCRYPT_MODE,privateKey);
// 私钥加密
byte[] bytes = cipher.doFinal(input.getBytes());
System.out.println(Base64.encode(bytes));
}}1234567891011121314151617181920212223242526272829303132337.3 私钥加密私钥解密public class RSAdemo2 {
public static void main(String[] args) throws Exception {
String input = "你好";
// 加密算法
String algorithm = "RSA";
// 创建密钥对生成器对象
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 生成私钥
PrivateKey privateKey = keyPair.getPrivate();
// 生成公钥
PublicKey publicKey = keyPair.getPublic();
// 获取私钥字节数组
byte[] privateKeyEncoded = privateKey.getEncoded();
// 获取公钥字节数组
byte[] publicKeyEncoded = publicKey.getEncoded();
// 对公私钥进行base64编码
String privateKeyString = Base64.encode(privateKeyEncoded);
String publicKeyString = Base64.encode(publicKeyEncoded);
// 创建加密对象
// 参数表示加密算法
Cipher cipher = Cipher.getInstance(algorithm);
// 初始化加密
// 第一个参数:加密的模式
// 第二个参数:使用私钥进行加密
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
// 私钥加密
byte[] bytes = cipher.doFinal(input.getBytes());
System.out.println("加密后:"+Base64.encode(bytes));
// 私钥进行解密
cipher.init(Cipher.DECRYPT_MODE, privateKey);
// 对密文进行解密,不需要使用base64,因为原文不会乱码
byte[] bytes1 = cipher.doFinal(bytes);
System.out.println("解密后:"+new String(bytes1));
}}12345678910111213141516171819202122232425262728293031323334353637383940
7.4 私钥加密公钥解密public class RSAdemo2 {
public static void main(String[] args) throws Exception {
String input = "你好";
// 加密算法
String algorithm = "RSA";
// 创建密钥对生成器对象
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 生成私钥
PrivateKey privateKey = keyPair.getPrivate();
// 生成公钥
PublicKey publicKey = keyPair.getPublic();
// 获取私钥字节数组
byte[] privateKeyEncoded = privateKey.getEncoded();
// 获取公钥字节数组
byte[] publicKeyEncoded = publicKey.getEncoded();
// 对公私钥进行base64编码
String privateKeyString = Base64.encode(privateKeyEncoded);
String publicKeyString = Base64.encode(publicKeyEncoded);
// 创建加密对象
// 参数表示加密算法
Cipher cipher = Cipher.getInstance(algorithm);
// 初始化加密
// 第一个参数:加密的模式
// 第二个参数:使用私钥进行加密
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
// 私钥加密
byte[] bytes = cipher.doFinal(input.getBytes());
System.out.println("加密后:"+Base64.encode(bytes));
// 公钥进行解密
cipher.init(Cipher.DECRYPT_MODE, publicKey);
// 对密文进行解密,不需要使用base64,因为原文不会乱码
byte[] bytes1 = cipher.doFinal(bytes);
System.out.println("解密后:"+new String(bytes1));
}}123456789101112131415161718192021222324252627282930313233343536373839407.5 保存公钥和私钥private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
// 获取密钥对生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 获取密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 获取公钥
PublicKey publicKey = keyPair.getPublic();
// 获取私钥
PrivateKey privateKey = keyPair.getPrivate();
// 获取byte数组
byte[] publicKeyEncoded = publicKey.getEncoded();
byte[] privateKeyEncoded = privateKey.getEncoded();
// 进行Base64编码
String publicKeyString = Base64.encode(publicKeyEncoded);
String privateKeyString = Base64.encode(privateKeyEncoded);
// 保存文件
FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.forName("UTF-8"));
FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.forName("UTF-8"));
}123456789101112131415161718197.6 读取私钥public static PrivateKey getPrivateKey(String priPath, String algorithm) throws Exception {
// 将文件内容转为字符串
String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset());
// 输出私钥
System.out.println(privateKeyString);
// 获取密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 构建密钥规范 进行Base64解码
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString));
// 生成私钥
return keyFactory.generatePrivate(spec);
}1234567891011127.7 读取公钥 public static PublicKey getPublicKey(String pulickPath, String algorithm) throws Exception {
// 将文件内容转为字符串
String publicKeyString = FileUtils.readFileToString(new File(pulickPath), Charset.defaultCharset());
System.out.println(publicKeyString);
// 获取密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 构建密钥规范 进行Base64解码
X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyString));
// 生成公钥
return keyFactory.generatePublic(spec);
}1234567891011127.8 RSA工具类<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version></dependency>12345 public class RSAUtil {
private static final String KEY_ALGORITHM = "RSA";
private static KeyPairGenerator keyPairGenerator;
// 为每一个字段生成公私密钥
public static void makeRsaKeys(String pubPath, String priPath, String user) throws Exception {
try {
keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//随机数生成器
SecureRandom random = new SecureRandom();
//设置KEY_SIZE位长的秘钥
int KEY_SIZE = 1024;
keyPairGenerator.initialize(KEY_SIZE, random);
//开始创建
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();//公钥
PrivateKey privateKey = keyPair.getPrivate();//私钥
//使用Base64进行转码
String publicKeyStr = Base64.encode(publicKey.getEncoded());
String privateKeyStr = Base64.encode(privateKey.getEncoded());
// 保存文件
FileUtils.writeStringToFile(new File(pubPath), publicKeyStr, Charset.forName("UTF-8"));
FileUtils.writeStringToFile(new File(priPath), privateKeyStr, Charset.forName("UTF-8"));
}
// 私钥加密
public static String privateKeyDecode(String data, int mode, String priPath) throws Exception {
// 将文件内容转为字符串
String privateKeyString = FileUtils.readFileToString(new File(priPath), Charset.defaultCharset());
// 输出私钥// System.out.println(privateKeyString);
// 获取密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 构建密钥规范 进行Base64解码
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString));
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(spec);
try {
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
if (mode == Cipher.ENCRYPT_MODE) {//加密
cipher.init(mode, privateKey);
return Base64.encode(cipher.doFinal(data.getBytes()));
} else if (mode == Cipher.DECRYPT_MODE) {//解密
cipher.init(mode, privateKey);
return new String(cipher.doFinal(Base64.decode(data)), StandardCharsets.UTF_8);
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 公钥解密
public static String publicKeyDecode(String data, String pulickPath, int mode) throws Exception {
// 将文件内容转为字符串
String publicKeyString = FileUtils.readFileToString(new File(pulickPath), Charset.defaultCharset());// System.out.println(publicKeyString);
// 获取密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 构建密钥规范 进行Base64解码
X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyString));
// 生成公钥
PublicKey publicKey = keyFactory.generatePublic(spec);
try {
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
if (mode == Cipher.ENCRYPT_MODE) {//加密
cipher.init(mode, publicKey);
return Base64.encode(cipher.doFinal(data.getBytes()));
} else if (mode == Cipher.DECRYPT_MODE) {//解密
cipher.init(mode, publicKey);
byte[] bytes = cipher.doFinal(Base64.decode(data));
return new String(bytes, StandardCharsets.UTF_8);
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws Exception {
String user = "root";
// 公钥路径
String pubPath = "D:\\IDEA\\encrypt-decrypt\\src\\main\\java\\com\\zwh\\key\\" + user + ".txt";
// 私钥路径
String priPath = "D:\\IDEA\\encrypt-decrypt\\src\\main\\java\\com\\zwh\\key\\" + user + "_en.txt";
makeRsaKeys(pubPath, priPath, user);
String str = "123456";
System.out.println("明文:" + str);
System.out.println("---------私钥加密,公钥解密-----------");
String privateKeyDecode = privateKeyDecode(str, 1, priPath);
System.out.println("私钥加密:" + privateKeyDecode);
String publicKeyDecode = publicKeyDecode(privateKeyDecode, pubPath, 2);
System.out.println("公钥解密:" + publicKeyDecode);
}}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011028 数字签名public class SignatureDemo {
public static void main(String[] args) throws Exception {
String a = "123";
PublicKey publicKey = RSAdemo4.getPublicKey("a.pub", "RSA");
PrivateKey privateKey = RSAdemo4.getPrivateKey("a.pri", "RSA");
String signaturedData = getSignature(a, "sha256withrsa", privateKey);
boolean b = verifySignature(a, "sha256withrsa", publicKey, signaturedData);
System.out.println(b);
System.out.println(signaturedData);
}
/**
* 生成签名
*
* @param input : 原文
* @param algorithm : 算法
* @param privateKey : 私钥
* @return : 签名
* @throws Exception
*/
private static String getSignature(String input, String algorithm, PrivateKey privateKey) throws Exception {
// 获取签名对象
Signature signature = Signature.getInstance(algorithm);
// 初始化签名
signature.initSign(privateKey);
// 传入原文
signature.update(input.getBytes());
// 开始签名
byte[] sign = signature.sign();
// 对签名数据进行Base64编码
return Base64.encode(sign);
}
/**
* 校验签名
*
* @param input : 原文
* @param algorithm : 算法
* @param publicKey : 公钥
* @param signaturedData : 签名
* @return : 数据是否被篡改
* @throws Exception
*/
private static boolean verifySignature(String input, String algorithm, PublicKey publicKey, String signaturedData) throws Exception {
// 获取签名对象
Signature signature = Signature.getInstance(algorithm);
// 初始化签名
signature.initVerify(publicKey);
// 传入原文
signature.update(input.getBytes());
// 校验数据
return signature.verify(Base64.decode(signaturedData));
}}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
该文章在 2023/6/2 10:10:50 编辑过 |
关键字查询
相关文章
正在查询... |