2019独角兽企业重金招聘Python工程师标准>>>

基本概念:

加密:发送方利用接受方的公钥对要发送的明文进行加密。

解密:接收方利用自己的私钥进行解密。

公钥与私钥是配对的,用公钥加密的文件,只有对应的私钥才能解密,反过来,用私钥加密,用对应的公钥进行解密。

签名:发送方用一个哈希函数从报文文本中生成报文摘要,然后用自己的私钥对摘要进行加密,得到的就是这个报文对应的数字签名,通常来说,发送方会将数字签名和报文原文一并发送接收者,方便接收者进行验签。

验签:接收方得到原始报文和数字签名后,用同一个哈希函数从报文中生成报文摘要A,另外,用发送方提供的公钥对数字签名进行解密,得到摘要B,对比A和B是否相同,就可得知报文有没有被篡改过。

公钥密码体制:

原理就是加密密钥与解密密钥分离,这样一个具体用户就可将自己设计的加密密钥和算法公诸于众,而只保密解密密钥。任何人都可利用这个加密密钥和算法向该用户发送加密信息,该用户均可通过解密密钥将之还原。公共密钥密码的优点就是不需要经安全渠道传递密钥,大大简化了密钥管理。它的算法又是也称之为公开密钥算法或简称公约算法。

公钥加密算法:

公钥加密算法中使用最广的是RSA,RSA使用两个密钥,一个公共密钥,一个专用密钥。如用其中一个加密,则可用另一个解密,密钥长度从40到2048bit可变。加密是也把明文分成快,块的大小可变,但不可能超过密钥的长度,RSA算法吧每一块明文转化为与密钥长度相同的密文块,密钥越长,加密效果越好,但加密解密的开销也大,所以在安全和性能之间折中考虑,一般64位较为合适。RSA的一个比较知名的应用是SSL,在美国和加拿大SSL用128位RSA算法,由于出口限制,在其他地区(包括中国)通用的则是40位版本。

RSA算法基于一个十分简单的数论事实:将两大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开座位加密密钥。质数:又称素数,有无限个。一个大于1的自然数,除了1和它本身以外,不能被其他自然数整除。

RSA算法涉及三个参数,n、e1、e2.其中,n是两个大指数p、q的积,n的二进制表示时所占用的尾数,就是密钥长度。e1和e2是一对相关的值,e1可以随意取,但要求e1与(p-1)*(q-1)互质;再选择e2,要求(e2*e1) mod((p-1)*(q-1))=1.

其中(n,e1),(n,e2)就是密钥对,其中(n,e1)为公钥,(n,e2)为私钥。RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e2 mod n;B=A^e1 mod n;(公钥加密机制中,一般用公钥加密,私钥解密)      e1和e2可以互换使用,即:A=B^e1 mod n;B=A^e2 mod n;

eg:

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
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.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;  import java.util.HashMap;
import java.util.Map;  import javax.crypto.Cipher;  /** * RSA安全编码组件 *  * @author 梁栋 * @version 1.0 * @since 1.0 */
public abstract class RSACoder extends Coder {  public static final String KEY_ALGORITHM = "RSA";  public static final String SIGNATURE_ALGORITHM = "MD5withRSA";  private static final String PUBLIC_KEY = "RSAPublicKey";  private static final String PRIVATE_KEY = "RSAPrivateKey";  /** * 用私钥对信息生成数字签名 *  * @param data *            加密数据 * @param privateKey *            私钥 *  * @return * @throws Exception */  public static String sign(byte[] data, String privateKey) throws Exception {  // 解密由base64编码的私钥  byte[] keyBytes = decryptBASE64(privateKey);  // 构造PKCS8EncodedKeySpec对象  PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  // KEY_ALGORITHM 指定的加密算法  KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  // 取私钥匙对象  PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);  // 用私钥对信息生成数字签名  Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  signature.initSign(priKey);  signature.update(data);  return encryptBASE64(signature.sign());  }  /** * 校验数字签名 *  * @param data *            加密数据 * @param publicKey *            公钥 * @param sign *            数字签名 *  * @return 校验成功返回true 失败返回false * @throws Exception *  */  public static boolean verify(byte[] data, String publicKey, String sign)  throws Exception {  // 解密由base64编码的公钥  byte[] keyBytes = decryptBASE64(publicKey);  // 构造X509EncodedKeySpec对象  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  // KEY_ALGORITHM 指定的加密算法  KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  // 取公钥匙对象  PublicKey pubKey = keyFactory.generatePublic(keySpec);  Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  signature.initVerify(pubKey);  signature.update(data);  // 验证签名是否正常  return signature.verify(decryptBASE64(sign));  }  /** * 解密<br> * 用私钥解密 *  * @param data * @param key * @return * @throws Exception */  public static byte[] decryptByPrivateKey(byte[] data, String key)  throws Exception {  // 对密钥解密  byte[] keyBytes = decryptBASE64(key);  // 取得私钥  PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);  // 对数据解密  Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  cipher.init(Cipher.DECRYPT_MODE, privateKey);  return cipher.doFinal(data);  }  /** * 解密<br> * 用私钥解密 *  * @param data * @param key * @return * @throws Exception */  public static byte[] decryptByPublicKey(byte[] data, String key)  throws Exception {  // 对密钥解密  byte[] keyBytes = decryptBASE64(key);  // 取得公钥  X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  Key publicKey = keyFactory.generatePublic(x509KeySpec);  // 对数据解密  Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  cipher.init(Cipher.DECRYPT_MODE, publicKey);  return cipher.doFinal(data);  }  /** * 加密<br> * 用公钥加密 *  * @param data * @param key * @return * @throws Exception */  public static byte[] encryptByPublicKey(byte[] data, String key)  throws Exception {  // 对公钥解密  byte[] keyBytes = decryptBASE64(key);  // 取得公钥  X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);  KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  Key publicKey = keyFactory.generatePublic(x509KeySpec);  // 对数据加密  Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  cipher.init(Cipher.ENCRYPT_MODE, publicKey);  return cipher.doFinal(data);  }  /** * 加密<br> * 用私钥加密 *  * @param data * @param key * @return * @throws Exception */  public static byte[] encryptByPrivateKey(byte[] data, String key)  throws Exception {  // 对密钥解密  byte[] keyBytes = decryptBASE64(key);  // 取得私钥  PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);  KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);  Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);  // 对数据加密  Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  cipher.init(Cipher.ENCRYPT_MODE, privateKey);  return cipher.doFinal(data);  }  /** * 取得私钥 *  * @param keyMap * @return * @throws Exception */  public static String getPrivateKey(Map<String, Object> keyMap)  throws Exception {  Key key = (Key) keyMap.get(PRIVATE_KEY);  return encryptBASE64(key.getEncoded());  }  /** * 取得公钥 *  * @param keyMap * @return * @throws Exception */  public static String getPublicKey(Map<String, Object> keyMap)  throws Exception {  Key key = (Key) keyMap.get(PUBLIC_KEY);  return encryptBASE64(key.getEncoded());  }  /** * 初始化密钥 *  * @return * @throws Exception */  public static Map<String, Object> initKey() throws Exception {  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;  }
}  

测试类

import static org.junit.Assert.*;  import org.junit.Before;
import org.junit.Test;  import java.util.Map;  /** *  * @author 梁栋 * @version 1.0 * @since 1.0 */
public class RSACoderTest {  private String publicKey;  private String privateKey;  @Before  public void setUp() throws Exception {  Map<String, Object> keyMap = RSACoder.initKey();  publicKey = RSACoder.getPublicKey(keyMap);  privateKey = RSACoder.getPrivateKey(keyMap);  System.err.println("公钥: \n\r" + publicKey);  System.err.println("私钥: \n\r" + privateKey);  }  @Test  public void test() throws Exception {  System.err.println("公钥加密——私钥解密");  String inputStr = "abc";  byte[] data = inputStr.getBytes();  byte[] encodedData = RSACoder.encryptByPublicKey(data, publicKey);  byte[] decodedData = RSACoder.decryptByPrivateKey(encodedData,  privateKey);  String outputStr = new String(decodedData);  System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);  assertEquals(inputStr, outputStr);  }  @Test  public void testSign() throws Exception {  System.err.println("私钥加密——公钥解密");  String inputStr = "sign";  byte[] data = inputStr.getBytes();  byte[] encodedData = RSACoder.encryptByPrivateKey(data, privateKey);  byte[] decodedData = RSACoder  .decryptByPublicKey(encodedData, publicKey);  String outputStr = new String(decodedData);  System.err.println("加密前: " + inputStr + "\n\r" + "解密后: " + outputStr);  assertEquals(inputStr, outputStr);  System.err.println("私钥签名——公钥验证签名");  // 产生签名  String sign = RSACoder.sign(encodedData, privateKey);  System.err.println("签名:\r" + sign);  // 验证签名  boolean status = RSACoder.verify(encodedData, publicKey, sign);  System.err.println("状态:\r" + status);  assertTrue(status);  }  }  

控制台输出

公钥:   MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYU/+I0+z1aBl5X6DUUOHQ7FZpmBSDbKTtx89J
EcB64jFCkunELT8qiKly7fzEqD03g8ALlu5XvX+bBqHFy7YPJJP0ekE2X3wjUnh2NxlqpH3/B/xm
1ZdSlCwDIkbijhBVDjA/bu5BObhZqQmDwIxlQInL9oVz+o6FbAZCyHBd7wIDAQAB  私钥:   MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJhT/4jT7PVoGXlfoNRQ4dDsVmmY
FINspO3Hz0kRwHriMUKS6cQtPyqIqXLt/MSoPTeDwAuW7le9f5sGocXLtg8kk/R6QTZffCNSeHY3
GWqkff8H/GbVl1KULAMiRuKOEFUOMD9u7kE5uFmpCYPAjGVAicv2hXP6joVsBkLIcF3vAgMBAAEC
gYBvZHWoZHmS2EZQqKqeuGr58eobG9hcZzWQoJ4nq/CarBAjw/VovUHE490uK3S9ht4FW7Yzg3LV
/MB06Huifh6qf/X9NQA7SeZRRC8gnCQk6JuDIEVJOud5jU+9tyumJakDKodQ3Jf2zQtNr+5ZdEPl
uwWgv9c4kmpjhAdyMuQmYQJBANn6pcgvyYaia52dnu+yBUsGkaFfwXkzFSExIbi0MXTkhEb/ER/D
rLytukkUu5S5ecz/KBa8U4xIslZDYQbLz5ECQQCy5dutt7RsxN4+dxCWn0/1FrkWl2G329Ucewm3
QU9CKu4D+7Kqdj+Ha3lXP8F0Etaaapi7+EfkRUpukn2ItZV/AkEAlk+I0iphxT1rCB0Q5CjWDY5S
Df2B5JmdEG5Y2o0nLXwG2w44OLct/k2uD4cEcuITY5Dvi/4BftMCZwm/dnhEgQJACIktJSnJwxLV
o9dchENPtlsCM9C/Sd2EWpqISSUlmfugZbJBwR5pQ5XeMUqKeXZYpP+HEBj1nS+tMH9u2/IGEwJA
fL8mZiZXan/oBKrblAbplNcKWGRVD/3y65042PAEeghahlJMiYquV5DzZajuuT0wbJ5xQuZB01+X
nfpFpBJ2dw==  公钥加密——私钥解密
加密前: abc  解密后: abc
公钥:   MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdOj40yEB48XqWxmPILmJAc7UecIN7F32etSHF
9rwbuEh3+iTPOGSxhoSQpOED0vOb0ZIMkBXZSgsxLaBSin2RZ09YKWRjtpCA0kDkiD11gj4tzTiM
l9qq1kwSK7ZkGAgodEn3yIILVmQDuEImHOXFtulvJ71ka07u3LuwUNdB/wIDAQAB  私钥:   MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAN06PjTIQHjxepbGY8guYkBztR5w
g3sXfZ61IcX2vBu4SHf6JM84ZLGGhJCk4QPS85vRkgyQFdlKCzEtoFKKfZFnT1gpZGO2kIDSQOSI
PXWCPi3NOIyX2qrWTBIrtmQYCCh0SffIggtWZAO4QiYc5cW26W8nvWRrTu7cu7BQ10H/AgMBAAEC
gYEAz2JWBizjI31bqhP4XiP9PuY5F3vqBW4T+L9cFbQiyumKJc58yzTWUAUGKIIn3enXLG7dNqGr
mbJro4JeFIJ3CiVDpXR9+FluIgI4SXm7ioGKF2NOMA9LR5Fu82W+pLfpTN2y2SaLYWEDZyp53BxY
j9gUxaxi1MQs+C1ZgDF2xmECQQDy70bQntbRfysP+ppCtd56YRnES1Tyekw0wryS2tr+ivQJl7JF
gp5rPAOXpgrq36xHDwUspQ0sJ0vj0O7ywxr1AkEA6SAaLhrJJrYucC0jxwAhUYyaPN+aOsWymaRh
9jA/Wc0wp29SbGTh5CcMuGpXm1g0M+FKW3dGiHgS3rVUKim4owJAbnxgapUzAgiiHxxMeDaavnHW
9C2GrtjsO7qtZOTgYI/1uT8itvZW8lJTF+9OW8/qXE76fXl7ai9dFnl5kzMk2QJBALfHz/vCsArt
mkRiwY6zApE4Z6tPl1V33ymSVovvUzHnOdD1SKQdD5t+UV/crb3QVi8ED0t2B0u0ZSPfDT/D7kMC
QDpwdj9k2F5aokLHBHUNJPFDAp7a5QMaT64gv/d48ITJ68Co+v5WzLMpzJBYXK6PAtqIhxbuPEc2
I2k1Afmrwyw=  私钥加密——公钥解密
加密前: sign  解密后: sign
私钥签名——公钥验证签名
签名:
ud1RsIwmSC1pN22I4IXteg1VD2FbiehKUfNxgVSHzvQNIK+d20FCkHCqh9djP3h94iWnIUY0ifU+
mbJkhAl/i5krExOE0hknOnPMcEP+lZV1RbJI2zG2YooSp2XDleqrQk5e/QF2Mx0Zxt8Xsg7ucVpn
i3wwbYWs9wSzIf0UjlM=  状态:
true  

转载于:https://my.oschina.net/zhangshuge/blog/801579

加密解密验签概念理解相关推荐

  1. 浅谈 加签验签 概念

    浅谈 加签验签 概念(一) 我们在求职面试中,经常会被问到,如何设计一个安全对外的接口呢? 其实可以回答这一点,加签和验签,这将让你的接口更加有安全.接下来,本文将和大家一起来学习加签和验签.从理论到 ...

  2. ECDSA算法加解密验签

    前段时间,因为公司业务需求研究了一下加密验签算法,找到了网上一位大佬的研究代码参考 Java中加密算法介绍及其实现 - 枫飘雪落 - 博客园 在大佬的研究中说明中找到了我需要的算法介绍,但是下载了大佬 ...

  3. RSA加密和验签的原理及方法

    RSA加密和验签的原理及方法 本文大纲 一.RSA加密简介 二.RSA加密.签名区别 三.RSA的加密过程 四.RSA签名的过程 一.RSA加密简介 RSA加密:属于非对称加密的范畴 这种加密方式可在 ...

  4. 小白都能看懂的目前主流加密MD5验签

    1, 首先要知道MD5 是一个什么东西 简单的说就是就是取模, 比如, 10 % 2, 余零, 2 想得出10, 就很难, 你只能猜. 现在有一个字符串 abcd, 下面都是假设 假设 a = 1, ...

  5. 在VUE中使用RSA加密解密加签

    RSA: 一般是客户端初始化时访问服务端时,服务端会生成一对RSA对,及公钥和私钥. 一,如果前端只需要将要传给后端的数据进行加密后传输,那么前端可以只要公钥,通过公钥对要传输的参数进行加密后把加密的 ...

  6. Python | Python 实现RSA加解密 验签 无 长度限制 加密解密, 分段加密

    系列文章目录 Python | Flask 解决跨域问题 文章目录 系列文章目录 为什么要分段加密 代码示例 测试 测试结果 为什么要分段加密 加密的字段长短规则如下: 加密的 plaintext 最 ...

  7. js rsa验签_js rsa sign使用笔记(加密,解密,签名,验签)

    你将会收获: js如何加密, 解密 js如何签名, 验签 js和Java交互如何相互解密, 验签(重点) 通过谷歌, 发现jsrsasign库使用者较多. 查看api发现这个库功能很健全. 本文使用方 ...

  8. 加密、解密、公钥、私钥、签名、验签

    加签.验签 「加签」:用Hash函数把原始报文生成报文摘要,然后用私钥对这个摘要进行加密,就得到这个报文对应的数字签名.通常来说呢,请求方会把「数字签名和报文原文」一并发送给接收方. 「验签」:接收方 ...

  9. .NET WebApi实现RSA加密与解密,签名与验签

    WebApi接口签名加密和验签 业务场景需求 生成RSA密钥对 报文根据规则进行排序 用请求方的私钥对报文签名 用接收方的公钥对报文加密 发送密文给接收方,用接收方的密钥解密 接收方对数据验签 关于C ...

最新文章

  1. 侧边栏配置_vscode入门:熟悉vscode和初级配置
  2. Fiddler 技术篇-捕捉https协议设置,抓取百度https实例演示
  3. Things That Cannot Change
  4. react 版权问题_react使用fetch封装请求的方法-简单易懂
  5. VirtualBox 桥接模式
  6. LeetCode刷题(15)
  7. wpf程序网络的影响_DotNetCore Web应用程序中的Cookie管理
  8. oracle中常用函数学习
  9. chrome Axure插件(Mac版)
  10. 从键盘上输入10个数,求其平均值。
  11. Angular 三目运算符
  12. 股票10档接口如何获取数据-步骤
  13. 运营简史:互联网运营的20年发展与演变
  14. Python学习手册之Python异常和文件
  15. 解决Linux“Device is busy”与磁盘只读
  16. nomad 服务编排_Nomad微服务的容器模式
  17. 如何进行自媒体创业?你是否能把握住,短视频都有哪些变现方式?
  18. 计算机CAD技术在工程设计中的应用,研究在机械工程设计中CAD技术的运用
  19. tp5 使用快递100的SDK
  20. 【人脸识别】HOG特征提取人脸识别【含Matlab源码 641期】

热门文章

  1. 真实揭秘90后程序员婚恋现状,有点扎心!
  2. 深大教学区Dr.com,实现校园网自动认证的请求
  3. 干货预警!自动化立体仓库电气安全设计
  4. 监控网络行为——公务员上班玩游戏
  5. 计算机科学和物理哪个难,据说这是期末考试难度最大的15个专业,你上榜了吗?...
  6. 中南大学计算机博士就业,求救!中南大学博士毕业要求
  7. 倾斜摄影超大场景的三维模型的顶层合并的轻量化处理技术
  8. 倾斜摄影测量(无人机影像)的三维建模和DSM,DOM的生成(挖坑)
  9. SVG格式文件可以用什么软件打开?
  10. Macbook Pro(MBP)上固态硬盘SSD,光驱位装HDD