RSA加密原理使用方式签名验证
RSA加密原理使用方式签名验证
加密是网络传输中非常重要的一环,它保证了信息的安全性,让他人无法通过抓包来获取通讯的信息也无法通过伪造信息而实现对系统的入侵。其中最为常用的信息传递加密方式就是RSA加密。
RSA加密原理
RSA与传统加密方式不同的是,他是非对称加密,可以在不直接传递密钥的情况下,完成解密。这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。
RSA加密方式是:
(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
(2)甲方获取乙方的公钥,然后用它对信息加密。
(3)乙方得到加密后的信息,用私钥解密。
RSA非对称加密算法的原理请参照下面两篇文章,本文主要讲述RSA加密在java程序中的使用。其概念是利用大整数的质数分解的困难性来保障密钥不被破解。
RSA加密传输的实现
在加密前首先要生成秘钥,秘钥的生成可以使用java中的security包下的KeyPairGenerator来生成指定位数的秘钥。生成的秘钥为byte类型,一般可以用文件保存在使用的时候读取,但是为了方便写在程序里也可以用base64编码成字符串,在使用的时候用base64解码然后获得秘钥的对象。
密钥生成:
/*创建非对称加密的公钥和私钥示例 将生成的公钥和私钥用Base64编码后打印出来*/
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); //一般加密位数为1024 对安全要求较高的情况下可以使用2048
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
/*将公钥base64编码打印出来*/ System.out.println(Base64.encodeBase64String(publicKey.getEncoded()));
/*将私钥base64编码打印出来*/ System.out.println(Base64.encodeBase64String(privateKey.getEncoded()));
加密我们需要先将密钥字符串base64解码然后生成密钥对象然后使用。
在java提供的jdk1.5中已经提供了相关加密工具类Cipher类,使用起来也比较方便
加密:
/*公钥字符串*/
String pubKey="base64编码的公钥";
/*X.509 标准中定义的公钥编码标准,使用这个类进行转换*/
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
//获得公钥对象
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
String msg="需要加密的内容";
/*使用Cipher加密*/
/*定义加密方式*/
Cipher cipher = Cipher.getInstance("RSA");
/*使用公钥和加密模式初始化*/
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
/*获取加密内容以UTF-8为标准转化的字节进行加密后再使用base64编码成字符串*/
/*加密后的字符串*/
String enmsg=Base64.encodeBase64String(cipher.doFinal(plainText.getBytes("UTF-8")));
然后同理反向解密
解密:
String priKey="base64编码的私钥";
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(baiduPriKey));
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
String msg="加密后的内容";
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
/*解密后的内容*/
String demsg = new String(cipher.doFinal(Base64.decodeBase64(msg)), "UTF-8");
以上就是加密解密的过程
RSA签名的实现
RSA加密生成的公钥和私钥实际上是一对互相可以加密解密的钥匙对,换句话说 你可以用私钥加密,用公钥解密。但是由于一些特定的加密工具为了方便加密传输位数而指定了公钥的秘钥值,私钥是根据公钥的值计算得出的,所以一般私钥比较大且安全性更高,留作自己系统去解密其他系统传来的数据。
但是我们说道,公钥是可能给复数个其他系统的,你无法得知是哪个系统给你传输的这个数据,所以就有了签名这一说。现在有甲乙两个系统,甲系统要给乙系统传输数据,甲系统的数据使用自己的私钥对传递的信息进行加密,然后加一个签名字段放入要传输的数据中然后整体数据再使用公钥进行加密,传输给乙系统。乙系统拿到数据后,先使用自己的私钥解密数据,然后剔除签名字段,然后解密签名字段看与剔除签名字段的数据进行对比,这一步叫做验签,如果相等则代表此数据时由甲方传来且数据没有被篡改。
java中也提供了相应的签名方法类Signature可以直接使用,现在假设使用json字符串传输做一次签名验签的案例
签名:
/* 1. 准备发送的数据 为保证顺序正确这里使用TreeMap*/
TreeMap<String, String> map = new TreeMap<String, String>();
map.put("msg1", "1324679");
map.put("msg2", "A001");
map.put("msg3", "V1.0");
map.put("msg4", "");
/* 2. 计算验签字段, sign字段不参与签名 map转String方法可以自定义*/
String line = JSON.toJSONString(map);
PrivateKey privateKey="自己的私钥";
//设置签名加密方式
Signature signature = Signature.getInstance("RSA");
signature.initSign(privateKey);//设置私钥
//签名和加密一样 要以字节形式 utf-8字符集得到字节
signature.update(line.getBytes("UTF-8"));
//得到base64编码的签名后的字段
String sign = Base64.encodeBase64String(signature.sign());
//将签名放入map
map.put("sign", sign);
//将要传输的数据转成json
String request = JSON.toJSONString(map);
/*进行传输(可进行正常加密)*/
.......
验签:
...
/*获得请求过来的request(若加密请解密)并转换成map*/
TreeMap<String, String> map = JSON.parseObject(request, new TypeReference<TreeMap<String, String>>() {});
String sign = map2.get("sign");//获得签名
map2.remove("sign");//剔除签名
String line = JSON.toJSONString(map);//转化为字符串
PublicKey publicKey = "对方给的公钥";
//指定签名类型
Signature signature = Signature.getInstance("RSA");
signature.initVerify(publicKey);//放入公钥
signature.update(line .getBytes("UTF-8"));//放入数据
//验签结果
boolean isPassed= signature.verify(Base64.decodeBase64(sign));
System.out.println("验签结果 : " + isPassed);
实际使用的优化方法
rsa算法是一种取模计算,当加密位数很大时(比如2048位生成密钥),实际上消耗的计算量还是很大的,而且由于有签名的存在,相当于传了两份数据过去,一正一反加密验签消耗的计算量就非常大了,为了优化加密传输及减少系统计算量,我们一般需要采取一些优化方法:
1.采取散列算法简化签名
签名实际上只需要验证数据是否没有被篡改/是否是对方系统发来的数据 实际上是没有必要吧整个数据都进行加密传输,可以使用散列算法来进行压缩验证,常用的有sha256和md5,然后将计算后的值进行签名,接收方使用同样的方法进行压缩验签。
2.生成随机对称加密密钥,使用对称加密加密数据,然后将密钥进行RSA加密明文传输
第一种优化虽然优化了签名,减少了数据传输和运算,但是数据本体还是很大,使用rsa加密仍然需要消耗大量的计算能力,于是就有了这种加密方式,生成随机的密钥对称加密数据,然后将对称的密钥进行rsa加密明文传输,对方接受到对称密钥的rsa加密后的字符串,再用私钥解密,得到对称加密的密钥对数据进行解密。
最后附上完整的加密案例及整理的加密解密工具类:
RSA加密原理使用方式签名验证的更多相关文章
- php rsa加密解密实例 及签名验证-自己实践
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2018/4/1 * Time: 1:50 */ //注意格式一 ...
- RSA加密原理与秘钥、公钥生成
RSA加密(非对称加密) RSA公开密钥密码体制.所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制.(不可逆向运算的加密方法) ...
- RSA加密的方式和解密方式
RSAsecurity.java package com.mstf.rsa; import java.security.KeyFactory; import java.security.KeyPair ...
- RSA 非对称加密原理(小白也能看懂哦~)
来源. https://blog.csdn.net/jijianshuai/article/details/80582187 RSA 加密原理 步骤 说明 描述 备注 1 找出质数 P .Q - 2 ...
- rsa加密初探
RSA加密算法初探 RSA加密算法是早期的非对称加密,公钥和私钥分离,公开公钥,通过确保私钥的安全来保证加密内容的安全.由麻省理工学院的罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi ...
- RSA加密、解密、公钥私钥生成
有时项目中需要用到一些加密和解密工具,这里之前整理了一个demo,记录一下,方便查询 package com.test; import java.security.KeyFactory; import ...
- When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)
关于网络安全的数据加密部分,本来打算总结一篇博客搞定,没想到东西太多,这已是第三篇了,而且这篇写了多次,熬了多次夜,真是again and again.起个名字:数据加密三部曲,前两部链接如下: 整体 ...
- Atitit RSA非对称加密原理与解决方案
Atitit RSA非对称加密原理与解决方案 1.1. 一.一点历史 1 1.2. 八.加密和解密 2 1.3. 二.基于RSA的消息传递机制 3 1.4. 基于rsa的授权验证机器码 4 1.5. ...
- IOS RSA 加密方式
采用RSA加密方式,主要是生成公钥和私钥,公钥用来加密,私钥用来解密,至于其中如何实现的,网上有很多原理. 参见如下: https://github.com/jslim89/RSA-objc PS: ...
随机推荐
- How to Pronounce TH after N or Z
How to Pronounce TH after N or Z Share Tweet Share Tagged With: Linking Consonant to Consonant The T ...
- Android RxJava 2 的用法 just 、from、map、subscribe、flatmap、Flowable、Function、Consumer ...【转】
先简单说说RxJava的用途与价值 原文出处:Android RxJava 2 的用法 用途: 异步 (也就是开线程跳转) 价值: 面对复杂的逻辑,它依然 简洁 ,代码 易读 RxJava2 与 Rx ...
- [重点]delphi 实现 根据给定的标题去《中国青年报》网上电子报数据中查找匹配的内容,并从该内容中取出引题、正题、副题、作者和正文。
项目要求:根据给定的标题去<中国青年报>网上电子报数据中查找匹配的内容,并从该内容中取出引题.正题.作者和正文. unit Unit1; interface uses Winapi.Win ...
- C# 图像处理:获取鼠标位置信息(全局)
Point ms = Control.MousePosition; //获取鼠标位置 this.label2.Text = string.Format("{0}:{1}", ms. ...
- FMS Dev Guide学习笔记(权限控制)
一.开发交互式的媒体应用程序 1.关于访问(权限)控制 当一个用户访问服务器的时候,默认情况下,他可以访问所有的流媒体文件和共享对象.但是你可以使用服务端ActionScript为流媒体文件和 ...
- python3进行汉字和unicode码的转换
输出某个unicode码对应的汉字和某个汉字对应的unicode编码. # -*- coding=UTF-8 -*- str1 = "\u6000"#某个汉字的unicode码 s ...
- Qt的action控件中采用默认绑定,没有connect显示绑定!!!
使用qt创建界面时,可以选用代码设计也可以选用qt design来设计.最近看我同事的代码,以前写action都是使用connect链接槽函数的, 网上大多数人都是这样,然后我就纳闷,怎么没有conn ...
- editplus设置自动换行方法 editplus自动换行设置步骤
原文链接:https://www.jb51.net/softjc/165897.html 发布时间:2014-05-14 17:03:54 作者:佚名 我要评论 editplus自动换行设置 ...
- Android Studio SVN配置
一 . 原文链接:忽略文件[转] https://blog.csdn.net/buaaroid/article/details/51546521 1.用Android Studio创建一个项目, ...
- 微信小程序开发攻略
首先,需要明确的一点是,小程序开发就是前端开发的一个小分支. 其次,小程序开发框架是一个精简版的React ,并且开发比较简单 . 第一步 获取AppId 小程序注册入口http://https:// ...