一般金融類(lèi)的產(chǎn)品,涉及前端和后端交互的時(shí)候,都會(huì)都嚴(yán)格的數(shù)據(jù)安全保證。防止黑客攻擊,信息篡改。
加密方式有很多,總的來(lái)說(shuō),分為2種:對(duì)稱(chēng)和非對(duì)稱(chēng)。我們先來(lái)看一下,這兩種加密方式分別是什么?他們有什么區(qū)別?
對(duì)稱(chēng)加密,即采用對(duì)稱(chēng)的密碼編碼技術(shù),他的特點(diǎn)是,加密和解密使用相同的秘鑰。
常見(jiàn)的對(duì)稱(chēng)加密算法有DES、3DES、Blowfish、IDEA、RC4、RC5、RC6和AES。對(duì)稱(chēng)加密算法使用起來(lái)簡(jiǎn)單快捷,密鑰較短,且破譯困難。
但是對(duì)稱(chēng)秘鑰在使用過(guò)程中存在以下問(wèn)題:
1、對(duì)稱(chēng)加密算法一般不能提供信息完整性的鑒別。它無(wú)法驗(yàn)證發(fā)送者和接受者的身份;
2、對(duì)稱(chēng)密鑰的管理和分發(fā)工作是一件具有潛在危險(xiǎn)的和煩瑣的過(guò)程。如何防止秘鑰泄露是一個(gè)難點(diǎn)。
非對(duì)稱(chēng)加密技術(shù),需要兩個(gè)秘鑰,公鑰和私鑰。公鑰和私鑰成對(duì)出現(xiàn)。
如果用公開(kāi)密鑰對(duì)數(shù)據(jù)進(jìn)行加密,只有用對(duì)應(yīng)的私有密鑰才能解密;如果用私有密鑰對(duì)數(shù)據(jù)進(jìn)行加密,那么只有用對(duì)應(yīng)的公開(kāi)密鑰才能解密。因?yàn)榧用芎徒饷苁褂玫氖莾蓚€(gè)不同的密鑰,所以這種算法叫作非對(duì)稱(chēng)加密算法。
非對(duì)稱(chēng)加密算法實(shí)現(xiàn)機(jī)密信息交換的基本過(guò)程是:甲方生成一對(duì)密鑰并將其中的一把作為公用密鑰向其它方公開(kāi);得到該公用密鑰的乙方使用該密鑰對(duì)機(jī)密信息進(jìn)行加密后再發(fā)送給甲方;甲方再用自己保存的另一把專(zhuān)用密鑰對(duì)加密后的信息進(jìn)行解密。甲方只能用其專(zhuān)用密鑰解密由其公用密鑰加密后的任何信息。
非對(duì)稱(chēng)加密的典型應(yīng)用是數(shù)字簽名。
常見(jiàn)的非對(duì)稱(chēng)加密算法有:RSA、ECC(移動(dòng)設(shè)備用)、Diffie-Hellman、El Gamal、DSA(數(shù)字簽名用)。
現(xiàn)在,我們已經(jīng)對(duì)對(duì)稱(chēng)和非對(duì)稱(chēng)加密有了一定的了解。接下來(lái),我將會(huì)給大家介紹一下,我在項(xiàng)目中使用的一種加密方式:對(duì)稱(chēng)+非對(duì)稱(chēng)。
先看一張流程圖:
先看發(fā)送方:
這里,我們主要有2步操作。
1、報(bào)文原文使用對(duì)稱(chēng)加密技術(shù)。對(duì)稱(chēng)加密的秘鑰(避免混淆,這里稱(chēng)對(duì)稱(chēng)密碼)。根據(jù)隨機(jī)數(shù)生成。每次發(fā)起請(qǐng)求時(shí),會(huì)重新產(chǎn)生一個(gè)隨機(jī)數(shù),進(jìn)一步降低被破解的風(fēng)險(xiǎn)。
2、對(duì)稱(chēng)密碼通過(guò)非對(duì)稱(chēng)加密方式進(jìn)行加密。公鑰由后臺(tái)產(chǎn)生,匹配的私鑰由后臺(tái)保管。這樣產(chǎn)生一個(gè)加密后的對(duì)稱(chēng)密碼。前端在發(fā)送給后端之后,后端需要用匹配的私鑰才能解開(kāi)。
再看接收方:
接收方在接收到數(shù)據(jù)包之后,同樣有兩步操作:
1、會(huì)使用匹配的私鑰解密加密的對(duì)稱(chēng)密碼,獲取到真實(shí)的對(duì)稱(chēng)密碼。
2、使用對(duì)稱(chēng)密碼,解密加密報(bào)文,獲取原報(bào)文內(nèi)容。
這樣做的好處是:
1、因?yàn)槲覀兊膶?duì)稱(chēng)密碼是使用非對(duì)稱(chēng)加密的,因此,想要破解,需要找到相應(yīng)的公鑰才行。
2、每次請(qǐng)求會(huì)重新生成一個(gè)對(duì)稱(chēng)密碼,這就加大了破解的難度。
public class RSA1 {
/**
* 隨機(jī)生成公鑰和私鑰
*/
public static final String publicKeyString = "publicKeyString";
public static final String privateKeyString = "privateKeyString";
public static HashMap<String, String> getRandomKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024);//生成大小 1024
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();//獲取公鑰
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();//獲取私鑰
HashMap<String, String> keyMap = new HashMap<String, String>();
keyMap.put(publicKeyString, new String(Base64.encode(publicKey.getEncoded(), Base64.DEFAULT)));//獲取公鑰Base64編碼
keyMap.put(privateKeyString, new String(Base64.encode(privateKey.getEncoded(), Base64.DEFAULT)));//獲取密鑰Base64編碼
return keyMap;
}
/**
* 通過(guò)字符串生成私鑰
*/
public static PrivateKey getPrivateKey(String privateKeyData) {
PrivateKey privateKey = null;
try {
byte[] decodeKey = Base64.decode(privateKeyData, Base64.DEFAULT); //將字符串Base64解碼
PKCS8EncodedKeySpec x509 = new PKCS8EncodedKeySpec(decodeKey);//創(chuàng)建x509證書(shū)封裝類(lèi)
KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定RSA
privateKey = keyFactory.generatePrivate(x509);//生成私鑰
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
/**
* 通過(guò)字符串生成公鑰
*/
public static PublicKey getPublicKey(String publicKeyData) {
PublicKey publicKey = null;
try {
byte[] decodeKey = Base64.decode(publicKeyData, Base64.DEFAULT);
X509EncodedKeySpec x509 = new X509EncodedKeySpec(decodeKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(x509);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
/**
* 加密
*/
public static byte[] encrypt(String data, Key key) {
try {
//取公鑰
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm(),"BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*/
public static byte[] decrypt(byte[] data, Key key) {
try {
Cipher cipher = Cipher.getInstance("RSA","BC");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public class AES_2 {
public static byte[] genPrivateKey(String password) throws NoSuchAlgorithmException {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
byte[] bytes = tohash256Deal(password);
SecureRandom securerandom = new SecureRandom(bytes);
kgen.init(128, securerandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
return key.getEncoded();
}
public static byte[] encrypt(String content, SecretKeySpec key) {
try {
//創(chuàng)建一個(gè)實(shí)現(xiàn)指定轉(zhuǎn)換的 Cipher對(duì)象,該轉(zhuǎn)換由指定的提供程序提供。
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] byteContent = content.getBytes("utf-8");
byte[] cryptograph = cipher.doFinal(byteContent);
return Base64.encode(cryptograph, Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decrypt(byte[] cryptograph, SecretKeySpec key) {
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] content = cipher.doFinal(Base64.decode(cryptograph, Base64.DEFAULT));
return new String(content);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static byte[] encrypt(String content, String password) {
try {
//"AES":請(qǐng)求的密鑰算法的標(biāo)準(zhǔn)名稱(chēng)
KeyGenerator kgen = KeyGenerator.getInstance("AES");
//256:密鑰生成參數(shù);securerandom:密鑰生成器的隨機(jī)源
SecureRandom securerandom = new SecureRandom(tohash256Deal(password));
kgen.init(128, securerandom);
//生成秘密(對(duì)稱(chēng))密鑰
SecretKey secretKey = kgen.generateKey();
//返回基本編碼格式的密鑰
byte[] enCodeFormat = secretKey.getEncoded();
//根據(jù)給定的字節(jié)數(shù)組構(gòu)造一個(gè)密鑰。enCodeFormat:密鑰內(nèi)容;"AES":與給定的密鑰內(nèi)容相關(guān)聯(lián)的密鑰算法的名稱(chēng)
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//將提供程序添加到下一個(gè)可用位置
Security.addProvider(new BouncyCastleProvider());
//創(chuàng)建一個(gè)實(shí)現(xiàn)指定轉(zhuǎn)換的 Cipher對(duì)象,該轉(zhuǎn)換由指定的提供程序提供。
//"AES/ECB/PKCS7Padding":轉(zhuǎn)換的名稱(chēng);"BC":提供程序的名稱(chēng)
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] byteContent = content.getBytes("utf-8");
byte[] cryptograph = cipher.doFinal(byteContent);
return Base64.encode(cryptograph, Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decrypt(byte[] cryptograph, String password) {
try {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom securerandom = new SecureRandom(tohash256Deal(password));
kgen.init(128, securerandom);
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] content = cipher.doFinal(Base64.decode(cryptograph, Base64.DEFAULT));
return new String(content);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
public static byte[] tohash256Deal(String datastr) {
try {
MessageDigest digester = MessageDigest.getInstance("SHA-256");
digester.update(datastr.getBytes());
byte[] hex = digester.digest();
return hex;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e.getMessage());
}
}
}
發(fā)送方和接收方的實(shí)現(xiàn):
String content = "000";
JSONObject jsonObject = new JSONObject();
try {
LogT.i("++++++++++++++++++++++發(fā)送方+++++++++++++++++++++++++=");
//產(chǎn)生私鑰
int random = (int) ((Math.random() * 9 + 1) * 100000);
//私鑰字節(jié)
byte[] bytes = AES_2.genPrivateKey(String.valueOf(random));
//傳輸報(bào)文加密
SecretKeySpec key1 = new SecretKeySpec(bytes, "AES");
byte[] content_encrypt = AES_2.encrypt(content, key1);
//公鑰對(duì)私鑰加密
PublicKey publicKey = RSA1.getPublicKey(public_key);
sKey_encrypt = RSA1.encrypt(Base64.encodeToString(bytes, Base64.DEFAULT), publicKey);
//數(shù)據(jù)組裝
jsonObject.put("key", Base64.encodeToString(sKey_encrypt, Base64.DEFAULT));
jsonObject.put("content", AES_2.parseByte2HexStr(content_encrypt));
LogT.i("+++++++++++++++++++++++接收方++++++++++++++++++++++++=");
//解析獲取私鑰
PrivateKey privateKey = RSA1.getPrivateKey(private_key);
//解析接收到的key數(shù)據(jù)
byte[] decode = Base64.decode(Base64.encodeToString(sKey_encrypt, Base64.DEFAULT), Base64.DEFAULT);
//私鑰解密
byte[] decrypt = RSA1.decrypt(decode, privateKey);
//解碼私鑰字節(jié)
byte[] decode_orig = Base64.decode(new String(decrypt), Base64.DEFAULT);
//加密的報(bào)文
byte[] HexStrByte = AES_2.parseHexStr2Byte(AES_2.parseByte2HexStr(content_encrypt));
SecretKeySpec key2 = new SecretKeySpec(decode_orig, "AES");
//解密后的報(bào)文
String decrypt1 = AES_2.decrypt(HexStrByte, key2);
LogT.i(decrypt1);//000
} catch (Exception e) {
e.printStackTrace();
}
原文:https://blog.csdn.net/Aminy123/article/details/81871092
聯(lián)系客服