一、关于接口安全加密传输对称加密与非对称加密的理解
一、什么是URL转码
1.不管是以何种方式传递url时,如果要传递的url中包含特殊字符,如想要传递一个+,但是这个+会被url会被编码成空格,想要传递&,被url处理成分隔符。 尤其是当传递的url是经过Base64加密或者RSA加密后的,存在特殊字符时,这里的特殊字符一旦被url处理,就不是原先你加密的结果了。
2.url特殊符号及对应的编码:
符号 |
url中的含义 |
编码 |
+ |
URL 中+号表示空格 |
%2B |
空格 |
URL中的空格可以用+号或者编码 |
%20 |
/ |
分隔目录和子目录 |
%2F |
?
|
分隔实际的URL和参数 |
%3F |
% |
指定特殊字符 |
%25 |
# |
表示书签 |
%23 |
& |
URL中指定的参数间的分隔符 |
%26 |
= |
URL中指定参数的值 |
%3D |
3.举个例子
3.1.项目结构
3.2.IndexController.java
//http协议特殊字符处理
@RestController
public class IndexController {
//1.什么是特殊字符处理(rpc远程通讯 实现加密)
@RequestMapping("/indexPage")
public String indexPage(String userName){
System.out.println("userName"+userName);
return userName;
}
}
3.3.访问结果(传入的结果传入+参数变为了空格)
3.4.解决办法:将+变为%2B(根据上面的表格转化一下)
二、什么是对称加密?
1.就是加密和解密都是同一个**,在加解密过程当中,使用的是同一个**进行加解密。
2.DES(数据加密标准):分组式加密,算法源于Lucifer,作为NIST对称式加密标准;64位(有效位56位、校验8位),分组算法
3DES:128位,分组算法
IDEA(国际数据加密算法):128位,比DES快,分组算法
Blowfish:32-448位,算法公开,分组算法
RC4:流密码,**长度可变
RC5:分组密码,**长度可变,最大2048位
Rijndael:128位/196位/256位
AES(高级加密标准):DES升级版,算法出自Rinjindael
三、DES加密(对称加密)
1.代码例子
/**
* DES加密介绍 DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同**的算法。DES加密算法出自IBM的研究,
* 后来被美国*正式采用,之后开始广泛流传,但是近些年使用越来越少,因为DES使用56位**,以现代计算能力,
* 24小时内即可被**。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现 。
* 注意:DES加密和解密过程中,**长度都必须是8的倍数
*/
public class DES {
public DES() {
}
// 测试
public static void main(String args[]) throws Exception {
// 待加密内容
String str = "chenmingxu1314";
// 密码,长度要是8的倍数 **随意定
String password = "13145210";
byte[] encrypt = encrypt(str.getBytes(), password);
System.out.println("加密后:" + new String(encrypt));
// 解密
byte[] decrypt = decrypt(encrypt, password);
System.out.println("解密后:" + new String(decrypt));
}
/**
* 加密
*
* @param datasource byte[]
* @param password String
* @return byte[]
*/
public static byte[] encrypt(byte[] datasource, String password) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂,然后用它把DESKeySpec转换成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象,ENCRYPT_MODE用于将 Cipher 初始化为加密模式的常量
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
// 现在,获取数据并加密
// 正式执行加密操作
return cipher.doFinal(datasource); // 按单部分操作加密或解密数据,或者结束一个多部分操作
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*
* @param src byte[]
* @param password String
* @return byte[]
* @throws Exception
*/
public static byte[] decrypt(byte[] src, String password) throws Exception {
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKey = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 返回实现指定转换的
// Cipher
// 对象
// 将DESKeySpec对象转换成SecretKey对象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 真正开始解密操作
return cipher.doFinal(src);
}
}
2.结果
加密后:%��kJK�;�n�Y�}
解密后:chenmingxu1314
3.对称加密优缺点
3.1.缺点:同一个**,如果前端传到后台用到这个加密的话,如果别人拿到你的源码,反编译之后就有可能获取到你的**,所以说这样是很不安全的。
3.2.优点:速度非常快,使用场景是后台与后台之间的通信,举个例子,机构网站与机构网站进行合作的情况下可以使用对称加密。
四、什么是非对称加密(RSA)?
1.首先非对称加密,分为一对**(必须组合公钥和私钥进行组合)。
2.使用第三方工具生成非对称**对。
3.如果使用公钥加密,那么必须要使用私钥解密。
如果使用私钥加密,那么必须要使用公钥解密。
公钥加密------私钥解密(安全),很常用。
私钥加密------公钥解密。
4.目前来说是最安全的加密手段,缺点:效率低,应用场景:第三方支付对接、核心金融机构。
五、RSA代码
1.代码例子
/**
* RSA加解密工具类
*/
public class RSAUtil {
public static String publicKey; // 公钥
public static String privateKey; // 私钥
/**
* 生成公钥和私钥
*/
public static void generateKey() {
// 1.初始化秘钥
KeyPairGenerator keyPairGenerator;
try {
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
SecureRandom sr = new SecureRandom(); // 随机数生成器
keyPairGenerator.initialize(512, sr); // 设置512位长的秘钥
KeyPair keyPair = keyPairGenerator.generateKeyPair(); // 开始创建
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
// 进行转码
publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded());
// 进行转码
privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 私钥匙加密或解密
*
* @param content
* @param privateKeyStr
* @return
*/
public static String encryptByprivateKey(String content, String privateKeyStr, int opmode) {
// 私钥要用PKCS8进行处理
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyStr));
KeyFactory keyFactory;
PrivateKey privateKey;
Cipher cipher;
byte[] result;
String text = null;
try {
keyFactory = KeyFactory.getInstance("RSA");
// 还原Key对象
privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(opmode, privateKey);
if (opmode == Cipher.ENCRYPT_MODE) { // 加密
result = cipher.doFinal(content.getBytes());
text = Base64.encodeBase64String(result);
} else if (opmode == Cipher.DECRYPT_MODE) { // 解密
result = cipher.doFinal(Base64.decodeBase64(content));
text = new String(result, "UTF-8");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return text;
}
/**
* 公钥匙加密或解密
*
* @param content
* @param privateKeyStr
* @return
*/
public static String encryptByPublicKey(String content, String publicKeyStr, int opmode) {
// 公钥要用X509进行处理
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyStr));
KeyFactory keyFactory;
PublicKey publicKey;
Cipher cipher;
byte[] result;
String text = null;
try {
keyFactory = KeyFactory.getInstance("RSA");
// 还原Key对象
publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(opmode, publicKey);
if (opmode == Cipher.ENCRYPT_MODE) { // 加密
result = cipher.doFinal(content.getBytes());
text = Base64.encodeBase64String(result);
} else if (opmode == Cipher.DECRYPT_MODE) { // 解密
result = cipher.doFinal(Base64.decodeBase64(content));
text = new String(result, "UTF-8");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return text;
}
// 测试方法
public static void main(String[] args) {
/**
* 注意: 私钥加密必须公钥解密 公钥加密必须私钥解密
*/
System.out.println("-------------生成两对秘钥,分别发送方和接收方保管-------------");
RSAUtil.generateKey();
System.out.println("公钥匙给接收方:" + RSAUtil.publicKey);
System.out.println("私钥给发送方:" + RSAUtil.privateKey);
System.out.println("-------------第一个栗子,私钥加密公钥解密-------------");
// String textsr = "早啊,你吃早饭了吗?O(∩_∩)O~";
// // 私钥加密
// String cipherText = RSAUtil.encryptByprivateKey(textsr,
// RSAUtil.privateKey, Cipher.ENCRYPT_MODE);
// System.out.println("发送方用私钥加密后:" + cipherText);
// // 公钥解密
// String text = RSAUtil.encryptByPublicKey(cipherText,
// RSAUtil.publicKey, Cipher.DECRYPT_MODE);
// System.out.println("接收方用公钥解密后:" + text);
System.out.println("-------------第二个栗子,公钥加密私钥解密-------------");
// 公钥加密
String textsr = "吃过啦!你吃了吗?O(∩_∩)O~";
String cipherText = RSAUtil.encryptByPublicKey(textsr, RSAUtil.publicKey, Cipher.ENCRYPT_MODE);
System.out.println("接收方用公钥加密后:" + cipherText);
// 私钥解密
String text = RSAUtil.encryptByprivateKey(cipherText, RSAUtil.privateKey, Cipher.DECRYPT_MODE);
System.out.print("发送方用私钥解密后:" + text);
}
}
2.测试代码
public class Test001 {
public static void main(String[] args) {
// 实现步骤:
// 1.生成公钥和私钥**对
RSAUtil.generateKey();
System.out.println("私钥:" + RSAUtil.privateKey);
System.out.println("公钥:" + RSAUtil.publicKey);
String content = "chenmingxu1314";
// 2.使用公钥进行加密
String encryptByPublicKey = RSAUtil.encryptByPublicKey(content, RSAUtil.publicKey, Cipher.ENCRYPT_MODE);
System.out.println("加密后:" + encryptByPublicKey);
String encryptByprivateKey = RSAUtil.encryptByprivateKey(encryptByPublicKey, RSAUtil.privateKey,
Cipher.DECRYPT_MODE);
// 3.使用私钥进行解密
System.out.println("解密后:" + encryptByprivateKey);
// 正常在开发中的时候,后端开发人员生成好**对,服务器端保存私钥 客户端保存公钥
}
}
3.测试结果
私钥:MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAsyohB5wXqQgR+BB9MNGIsux0VgxBhyDmwUKVTtDYAr4pMdRahsYZ21nWwHkQMwl4Psio2r+9Rfb2qWsrbY4xSQIDAQABAkBNyvUcgMIlOsPSmhZBpDletxysYBXzvm1zbJ234yZnybz2Ye4qlRc28r6YF7tJXJV4yRDdFBm85wmVLFjmxZ8hAiEA/wWbo5HueQ1DsE3E3VIDskHqHIWStOEdi07zlgKA+88CIQCz2gp38P+gslwzKU8MpxZWUBSnxTCR68mZcuJC+8xPZwIhANSNeQZhGDEexB8LAp0wwVHurFDvZ7KIupYkzNNn7NdzAiEAgkpB7TQMq+iqPHH/j0X4O50V6ZhDoGJ1EJIWcboh/58CICLbWBPQNxWfn0bgTKLCnQwbvM1lYA5/mygFlMUTU7QP
公钥:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALMqIQecF6kIEfgQfTDRiLLsdFYMQYcg5sFClU7Q2AK+KTHUWobGGdtZ1sB5EDMJeD7IqNq/vUX29qlrK22OMUkCAwEAAQ==
加密后:rcdusr+460g9KOkeybQwpE2o/pg+x4eMFn7JdxBRUReHTP3mZJDUPQ9jenW+g8OHN1veo/7azNA4Nb5S043ekg==
解密后:chenmingxu1314
六、结束
今天就写到这里吧,有时间再研究下MD5加密。晚安各位!!!
上一篇: PHP实现返回JSON和XML的类分享
下一篇: Https与对称加密和非对称加密的关系