支付安全_信息安全的基础
密码学基本概念
密码学是网络安全、信息安全、区块链等产品的基础,常见的非对称加密、对称加密、散列函数等,都属于密码学范畴。
中国古代加密
公元683年,唐中宗即位。随后,武则天废唐中宗,立第四子李旦为皇帝,但朝政大事均由她自己专断。裴炎、徐敬业和骆宾王等人 对此非常不满。徐敬业聚兵十万,在江苏扬州起兵。裴炎做内应, 欲以拆字手段为其传递秘密信息。后因有人告密,裴炎被捕,未发出的密信落到武则天手中。这封密信上只有“青鹅”二字,群臣对此大惑不解。
破解:
武则天破解了“青鹅”的秘密:“青”字拆开来就是“十二月”,而“鹅” 字拆开来就是“我自与”。密信的意思是让徐敬业、骆宾王等率兵 于十二月进发,裴炎在内部接应。“青鹅”破译后,裴炎被杀。接着,武则天派兵击败了徐敬业和骆宾王。
明文
加密前的消息叫“明文”(plain text)。
密文
加密后的文本叫“密文”(cipher text)。
密钥
只有掌握特殊“钥匙”的人,才能对加密的文本进行解密,这里的“钥 匙”就叫做“密钥”(key)。
1.下列属于非对称加密算法的是____。RSA
支付安全_消息摘要
摘要算法就是我们常说的散列函数、哈希函数(Hash Function),它能够把任意长度的数据“压缩”成固定长度、而且独 一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”。
作用:
保证信息的完整性
回顾之前数字摘要
百度搜索 MySQL ,进入官网下载 ,会经常发现有 sha1 , sha512 , 这些 都是数字摘要。
点击signature
消息摘要实现
public static void main(String[] args) throws Exception{ // 原文 String input = "xiaotong"; // 算法 String algorithm = "MD5"; // 获取数字摘要对象 MessageDigest messageDigest = MessageDigest.getInstance(algorithm); // 获取消息数字摘要的字节数组 byte[] digest = messageDigest.digest(input.getBytes()); System.out.println(new String(digest)); }
注意: 加密后编码表找不到对应字符, 出现乱码
base64 编码
public static void main(String[] args) throws Exception{ // 原文 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(new BASE64Encoder().encode(digest)); }
1.下列可以实现消息摘要算法的是__。MD5
2.消息摘要算法主要作用_______。保证数据完整性
支付安全_对称加密
对称加密
对称加密指的就是加密和解密使用同一个秘钥,所以叫做对称加密。对称加密只有一个秘钥,作为私钥。
对称加密实现
package com.itbaizhan.encryption; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; /** * DesAesDemo */ public class DesAesDemo { public static void main(String[] args) throws Exception { // 原文 String input = "xiaotong"; // des加密必须是8位 String key = "123456"; // 算法 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)); } }
报错
注意: 密钥是6个字节,DES加密算法规定,密钥key必须是8个字节, 所以需要修改上面key改成key="12345678"
注意: 出现乱码是因为对应的字节出现负数,但负数,没有出现在 ascii 码表里面,所以出现乱码,需要配合base64进行转码。
解密
package com.itbaizhan.encryption; import cn.hutool.core.codec.Base64; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; /** * DesAesDemo */ public class DesAesDemo { public static void main(String[] args) throws Exception { // 原文 String input = "baizhan"; // des加密必须是8位 String key = "12345678"; // 算法 String algorithm = "DES"; String transformation = "DES"; String s = encryptDES(input, key, algorithm, transformation); String test = "znLsz/8WnU4="; String s1 = decryptDES(test, key, algorithm, transformation); System.out.println(s1); } /** * 使用DES加密数据 * * @param input : 原文 * @param key : 密钥(DES,密钥的长度必须是8个字节) * @param transformation : 获取Cipher对象的算法 * @param algorithm : 获取密钥的算法 * @return : 密文 * @throws Exception */ private 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; } /** * 使用DES解密 * * @param input : 密文 * @param key : 密钥 * @param transformation : 获取Cipher对象的算法 * @param algorithm : 获取密钥的算法 * @throws Exception * @return: 原文 */ private static String decryptDES(Stringinput, 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); } }
1.对称加密采用___钥密码系统的加密方法。单
2.下列属于对称加密算法的是_____。DES
支付安全_非对称加密
非对称加密
非对称加密指的是:加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥。公钥加密的信息,只有私钥才能解密。私钥加密的信息,只有公钥才能解密。
非对称加密实现
引入依赖
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>
生成公钥和私钥
import com.sun.org.apache.xml.internal.security.utils.Base64; import org.apache.commons.io.FileUtils; import javax.crypto.Cipher; import java.io.File; import java.nio.charset.Charset; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; /** * 生成公钥和私钥 */ public class RSAdemo { public static void main(String[] args) throws Exception { String input = "xiaotong"; // 加密算法 String algorithm = "RSA"; //生成密钥对并保存在本地文件中 generateKeyToFile(algorithm, "a.pub","a.pri"); } /** * 生成密钥对并保存在本地文件中 * * @param algorithm : 算法 * @param pubPath : 公钥保存路径 * @param priPath : 私钥保存路径 * @throws Exception */ 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")); }
运行程序:先打印的是私钥 , 后面打印的是公钥
私钥加密
/** * 读取私钥 * @param priPath * @param algorithm * @return * @throws Exception */ public static PrivateKey getPrivateKey(String priPath,String algorithm) throws Exception{ // 将文件内容转为字符串 String privateKeyString = FileUtils.readFileToString(new File(priPath),Charset.defaultCharset()); // 获取密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(algorithm); // 构建密钥规范 进行Base64解码 PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKeyString)); // 生成私钥 return keyFactory.generatePrivate(spec); } public static void main(String[] args) throws Exception { String input = "xiaotong"; // 加密算法 String algorithm = "RSA"; // 加载私钥 PrivateKey privateKey = getPrivateKey("a.pri", algorithm); // 私钥加密 String s = encryptRSA(algorithm, privateKey, input); System.out.println(s); }
公钥加密
/** * 读取公钥 * @param pulickPath * @param algorithm * @return * @throws Exception */ public static PublicKey getPublicKey(String pulickPath,String algorithm) throws Exception{ // 将文件内容转为字符串 String publicKeyString = FileUtils.readFileToString(new File(pulickPath), Charset.defaultCharset()); // 获取密钥工厂 KeyFactory keyFactory = KeyFactory.getInstance(algorithm); // 构建密钥规范 进行Base64解码 X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(publicKeyStrin g)); // 生成公钥 return keyFactory.generatePublic(spec); } public static void main(String[] args) throws Exception { String input = "xiaotong"; // 加密算法 String algorithm = "RSA"; // 加载公钥 PublicKey publicKey = getPublicKey("a.pub", algorithm); // 公钥解密 String s = encryptRSA(algorithm, publicKey, "密文"); System.out.println(s); }
1.下列加密算法中属于非对称加密的是__。RSA