加密分為對稱加密,非對稱加密肛宋, 不可逆加密州藕。
對稱加密:
描述: 加密解密使用同樣的密鑰。
特點: 速度快酝陈,安全性一般床玻。
舉例:DES、3DES沉帮、AES
使用場景:對大量數(shù)據(jù)進行加解密锈死。
非對稱加密:
描述:加解密使用不同的密鑰。
特點:速度慢穆壕,安全性較高待牵。
舉例:RSA
使用場景:在對稱加密前,使用非對稱加密傳輸公共的密鑰粱檀。
不可逆加密:
描述:只能加密洲敢,不能解密,加密過程不可逆茄蚯。
特點:不可逆加密压彭。
舉例:md5
使用場景:使用md5(md5(password)),使用雙重不可逆加密對用戶密碼加密渗常,并存入數(shù)據(jù)庫壮不。在驗證用戶密碼的時候,將待驗證的數(shù)據(jù)進行雙重加密后與數(shù)據(jù)庫中的數(shù)據(jù)作比較即可皱碘。
RSA加解密
RSA元素:
公鑰:發(fā)給對方
私鑰:自己保留
說明:
a 公鑰加密后询一,私鑰可以解密。
b 私鑰加密后公鑰可以解密癌椿。
c 私鑰簽名后健蕊,公鑰可以驗簽。
d 密鑰長度一般有:1024bits(128bytes) 2048bits(256bytes) 3072bits 4096bits踢俄。
e 密文長度一般等于密鑰長度缩功。(128bytes 256bytes)
f 待加密數(shù)據(jù)的長度:
RSA_PKCS1_PADDING RSA_size(128bytes) - 11 padding(11bytes) =117bytes
RSA_NO_PADDING RSA_size(128bytes) - 0 = 128bytes
RSA_X931_PADDING RSA_size(128bytes) - 2 padding(2bytes) = 126bytes
常用用法:
a. 公鑰加密,私鑰解密都办。
b. 私鑰加密并簽名嫡锌,公鑰驗簽并解密虑稼。
常見問題:
RSA對待加密的數(shù)據(jù)有長度限制(Data must not be longer than 117 bytes),需要分塊加密势木。
實際應用場景:
1--通信雙方A和B各自生成一對密鑰對(公鑰蛛倦,私鑰)。
2--A和B交換公鑰啦桌。
3--根據(jù)DH算法計算出一個A和B共有的共享密鑰
(原理:shareKey = A_privateKey * B_publicKey = A_publicKey * B_privateKey)溯壶。這只是示意,實際的DH運算是:
設(shè)有這么一個二元組 (q, p) = (3, 7)
我們定義Alice和Bob這么一個運算:
(1)Alice 選擇一個范圍在[1, p-1]的隨機數(shù)震蒋,為da= 5
(2)Alice 計算Pa = q^da mod p = 3^5 mod 7 = 5
(3)Bob選擇一個范圍在[1, p-1]的隨機數(shù)茸塞,為db = 6
(4)Bob計算Pb = q^db mod p = 3^6 mod 7 = 1
(5)Alice和Bob交換Pa和Pb
(6)Alice計算共享密鑰S = Pb ^da mod p = 1^5 mod 7 = 1
(7)Bob計算共享密鑰S = Pa ^db mod p = 5^6 m 7 = 1
4--使用shareKey來進行對稱加密。
有證書應用場景:
1--通信雙方A和B各自生成一對密鑰對(公鑰查剖,私鑰)钾虐。
2--使用證書系統(tǒng)根私鑰對公鑰進行簽名生成公鑰證書A和公鑰證書B。
3--A笋庄,B交換公鑰證書效扫。
4--A和B使用證書系統(tǒng)根證書對公鑰證書進行驗簽。
5--驗簽通過后提取公鑰直砂。
6--根據(jù)DH算法計算出一個A和B共有的共享密鑰
(原理:shareKey = A_privateKey * B_publicKey = A_publicKey * B_privateKey)菌仁。
7--使用shareKey來進行對稱加密。
RSA 加解密實例程序
代碼:
依賴第三方類庫:javabase64-1.3.1.jar
下載地址:https://sourceforge.net/projects/java-base64/files/
Base64Utils.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import it.sauronsoftware.base64.Base64;
/** *//**
* <p>
* BASE64編碼解碼工具包
* </p>
* <p>
* 依賴javabase64-1.3.1.jar
* </p>
*
* @author IceWee
* @date 2012-5-19
* @version 1.0
*/
public class Base64Utils {
/** *//**
* 文件讀取緩沖區(qū)大小
*/
private static final int CACHE_SIZE = 1024;
/** *//**
* <p>
* BASE64字符串解碼為二進制數(shù)據(jù)
* </p>
*
* @param base64
* @return
* @throws Exception
*/
public static byte[] decode(String base64) throws Exception {
return Base64.decode(base64.getBytes());
}
/** *//**
* <p>
* 二進制數(shù)據(jù)編碼為BASE64字符串
* </p>
*
* @param bytes
* @return
* @throws Exception
*/
public static String encode(byte[] bytes) throws Exception {
return new String(Base64.encode(bytes));
}
/** *//**
* <p>
* 將文件編碼為BASE64字符串
* </p>
* <p>
* 大文件慎用静暂,可能會導致內(nèi)存溢出
* </p>
*
* @param filePath 文件絕對路徑
* @return
* @throws Exception
*/
public static String encodeFile(String filePath) throws Exception {
byte[] bytes = fileToByte(filePath);
return encode(bytes);
}
/** *//**
* <p>
* BASE64字符串轉(zhuǎn)回文件
* </p>
*
* @param filePath 文件絕對路徑
* @param base64 編碼字符串
* @throws Exception
*/
public static void decodeToFile(String filePath, String base64) throws Exception {
byte[] bytes = decode(base64);
byteArrayToFile(bytes, filePath);
}
/** *//**
* <p>
* 文件轉(zhuǎn)換為二進制數(shù)組
* </p>
*
* @param filePath 文件路徑
* @return
* @throws Exception
*/
public static byte[] fileToByte(String filePath) throws Exception {
byte[] data = new byte[0];
File file = new File(filePath);
if (file.exists()) {
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
byte[] cache = new byte[CACHE_SIZE];
int nRead = 0;
while ((nRead = in.read(cache)) != -1) {
out.write(cache, 0, nRead);
out.flush();
}
out.close();
in.close();
data = out.toByteArray();
}
return data;
}
/** *//**
* <p>
* 二進制數(shù)據(jù)寫文件
* </p>
*
* @param bytes 二進制數(shù)據(jù)
* @param filePath 文件生成目錄
*/
public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
InputStream in = new ByteArrayInputStream(bytes);
File destFile = new File(filePath);
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
destFile.createNewFile();
OutputStream out = new FileOutputStream(destFile);
byte[] cache = new byte[CACHE_SIZE];
int nRead = 0;
while ((nRead = in.read(cache)) != -1) {
out.write(cache, 0, nRead);
out.flush();
}
out.close();
in.close();
}
}
RSAUtils.java
改進點:
1 增加了try catch 济丘,不用將異常拋出。這樣可以給類的變量賦值洽蛀。生成密鑰對的時候使用摹迷。
2 增加了將公鑰和私鑰存儲到文件的功能。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
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.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
/** *//**
* <p>
* RSA公鑰/私鑰/簽名工具包
* </p>
* <p>
* 羅納德·李維斯特(Ron [R]ivest)郊供、阿迪·薩莫爾(Adi [S]hamir)和倫納德·阿德曼(Leonard [A]dleman)
* </p>
* <p>
* 字符串格式的密鑰在未在特殊說明情況下都為BASE64編碼格式<br/>
* 由于非對稱加密速度極其緩慢峡碉,一般文件不使用它來加密而是使用對稱加密,<br/>
* 非對稱加密算法可以用來對對稱加密的密鑰加密驮审,這樣保證密鑰的安全也就保證了數(shù)據(jù)的安全
* </p>
*
* @author IceWee
* @date 2012-4-26
* @version 1.0
*/
public class RSAUtils {
/** *//**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/** *//**
* 簽名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/** *//**
* 獲取公鑰的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/** *//**
* 獲取私鑰的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/** *//**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
/** *//**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/** *//**
* <p>
* 生成密鑰對(公鑰和私鑰)
* </p>
*
* @return
* @throws Exception
*/
public static Map<String, Object> genKeyPair() {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
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;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 用私鑰對信息生成數(shù)字簽名
* </p>
*
* @param data 已加密數(shù)據(jù)
* @param privateKey 私鑰(BASE64編碼)
*
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) {
try {
byte[] keyBytes = Base64Utils.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 Base64Utils.encode(signature.sign());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 校驗數(shù)字簽名
* </p>
*
* @param data 已加密數(shù)據(jù)
* @param publicKey 公鑰(BASE64編碼)
* @param sign 數(shù)字簽名
*
* @return
* @throws Exception
*
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
byte[] keyBytes = Base64Utils.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(Base64Utils.decode(sign));
}
/** *//**
* <P>
* 私鑰解密
* </p>
*
* @param encryptedData 已加密數(shù)據(jù)
* @param privateKey 私鑰(BASE64編碼)
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)
{
try {
byte[] keyBytes = Base64Utils.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;
// 對數(shù)據(jù)分段解密
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;
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 公鑰解密
* </p>
*
* @param encryptedData 已加密數(shù)據(jù)
* @param publicKey 公鑰(BASE64編碼)
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)
{
try {
byte[] keyBytes = Base64Utils.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;
// 對數(shù)據(jù)分段解密
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;
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 公鑰加密
* </p>
*
* @param data 源數(shù)據(jù)
* @param publicKey 公鑰(BASE64編碼)
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey)
{
try {
byte[] keyBytes = Base64Utils.decode(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 對數(shù)據(jù)加密
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;
// 對數(shù)據(jù)分段加密
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;
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 私鑰加密
* </p>
*
* @param data 源數(shù)據(jù)
* @param privateKey 私鑰(BASE64編碼)
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey)
{
try {
byte[] keyBytes = Base64Utils.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;
// 對數(shù)據(jù)分段加密
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;
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 獲取私鑰
* </p>
*
* @param keyMap 密鑰對
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Object> keyMap)
{
try {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64Utils.encode(key.getEncoded());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 獲取公鑰
* </p>
*
* @param keyMap 密鑰對
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Object> keyMap)
{
try {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64Utils.encode(key.getEncoded());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 獲取私鑰
* </p>
*
* @param privateKeystore 讀取存儲私鑰的文件
* @return
* @throws Exception
*/
public static String readPrivateKeyFile(String privateKeystore)
{
try {
StringBuilder privateKey = new StringBuilder();
FileReader fr = new FileReader(privateKeystore);
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
privateKey.append(line);
}
br.close();
fr.close();
return privateKey.toString();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 獲取公鑰
* </p>
*
* @param publicKeystore 存儲公鑰的文件
* @return
* @throws Exception
*/
public static String readPublicKeyFile(String publicKeystore)
{
try {
StringBuilder publicKey = new StringBuilder();
FileReader fr = new FileReader(publicKeystore);
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
publicKey.append(line);
}
br.close();
fr.close();
return publicKey.toString();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/** *//**
* <p>
* 存儲私鑰到文件
* </p>
*
* @param privateKey 私鑰字符串
* @param privateKeystore 存儲私鑰的文件
* @return
* @throws Exception
*/
public static void writePrivateKeyFile(String privateKey, String privateKeystore)
{
try {
FileWriter fw = new FileWriter(privateKeystore);
fw.write(privateKey);
fw.flush();
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/** *//**
* <p>
* 存儲公鑰到文件
* </p>
*
* @param publicKey 公鑰文件
* @param publicKeystore 存儲公鑰的文件
* @return
* @throws Exception
*/
public static void writePublicKeyFile(String publicKey, String publicKeystore)
{
try {
FileWriter fw = new FileWriter(publicKeystore);
fw.write(publicKey);
fw.flush();
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void testEncryptAndSignByPrivateKey(String publicKey, String privateKey) {
System.err.println("私鑰加密<===>公鑰解密");
String source = "1. 這是測試通過私鑰加密鲫寄,公鑰解密的測試源數(shù)據(jù)" +
"2. 這是測試通過私鑰加密,公鑰解密的測試源數(shù)據(jù)" +
"3. 這是測試通過私鑰加密疯淫,公鑰解密的測試源數(shù)據(jù)" +
"4. 這是測試通過私鑰加密地来,公鑰解密的測試源數(shù)據(jù)" +
"5. 這是測試通過私鑰加密,公鑰解密的測試源數(shù)據(jù)" +
"6. 這是測試通過私鑰加密熙掺,公鑰解密的測試源數(shù)據(jù)" +
"7. 這是測試通過私鑰加密未斑,公鑰解密的測試源數(shù)據(jù)" +
"8. 這是測試通過私鑰加密,公鑰解密的測試源數(shù)據(jù)" +
"9. 這是測試通過私鑰加密适掰,公鑰解密的測試源數(shù)據(jù)" +
"10. 這是測試通過私鑰加密颂碧,公鑰解密的測試源數(shù)據(jù)"
;
System.out.println("加密前的數(shù)據(jù):\r\n" + source);
byte[] data = source.getBytes();
try {
byte[] encodeData = RSAUtils.encryptByPrivateKey(data, privateKey);
System.out.println("加密后的數(shù)據(jù):\r\n" + new String(encodeData));
byte[] decodeData = RSAUtils.decryptByPublicKey(encodeData, publicKey);
System.out.println("解密后的數(shù)據(jù): \r\n" + new String(decodeData));
System.err.println("私鑰簽名<===>公鑰驗簽");
String sign = RSAUtils.sign(decodeData, privateKey);
System.out.println("簽名數(shù)據(jù): \r\n" + sign);
boolean status = RSAUtils.verify(decodeData, publicKey, sign);
System.out.println("驗簽結(jié)果:\r\n" + status);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
public static void testEncryptByPublicKey(String publicKey, String privateKey) {
System.err.println("公鑰加密<===>私鑰解密");
String source = "這是測試公鑰加密,私鑰解密的測試源數(shù)據(jù)";
System.out.println("加密前的數(shù)據(jù):\r\n" + source);
// byte[] data = source.getBytes();
try {
byte[] data = source.getBytes();
byte[] encodedData = RSAUtils.encryptByPublicKey(data, publicKey);
System.out.println("加密后的數(shù)據(jù): \r\n" + new String(encodedData));
byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey);
System.out.println("解密后的數(shù)據(jù): \r\n" + new String(decodedData));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
String publicKey;
String privateKey;
try {
Map<String, Object> keyMap = RSAUtils.genKeyPair();
publicKey = RSAUtils.getPublicKey(keyMap);
privateKey = RSAUtils.getPrivateKey(keyMap);
System.err.println("PublicKey: \r\n" + publicKey);
System.err.println("PrivateKey: \r\n" + privateKey);
Thread.sleep(100);
testEncryptByPublicKey(publicKey, privateKey);
Thread.sleep(100);
testEncryptAndSignByPrivateKey(publicKey, privateKey);
System.err.println("測試存儲公鑰文件: ");
String publicKeystore = "D:\\test\\RSA\\publicKey.store";
writePublicKeyFile(publicKey, publicKeystore);
System.out.println("write ok");
Thread.sleep(100);
System.err.println("測試讀取公鑰文件: ");
String readPublicKey = readPublicKeyFile(publicKeystore);
System.out.println("讀取的公鑰文件:\r\n" + readPublicKey);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
程序運行結(jié)果:
參考
DH算法:
https://blog.csdn.net/y_xianjun/article/details/81327943
MD5與對稱加密类浪、非對稱加密算法的比較:
https://blog.csdn.net/wangpeng322/article/details/84106548
java對稱加密與非對稱加密(DES载城、AES、RSA的實現(xiàn)):
https://blog.csdn.net/chengbinbbs/article/details/78640589
RSA密鑰長度费就、明文長度和密文長度
https://blog.csdn.net/luoluo_onion/article/details/78354799