[Linux] 使用openssl实现RSA非对称加密
简单定义:公钥和私钥,加密和解密使用的是两个不同的密钥,所以是非对称
系统:ubuntu 14.04
软件:openssl java php
生成公钥私钥
使用命令生成私钥:
openssl genrsa -out rsa_private_key.pem 1024
参数:genrsa 生成密钥 -out 输出到文件 rsa_private_key.pem 文件名 1024 长度
从私钥中提取公钥:
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
参数: rsa 提取公钥 -in 从文件中读入 rsa_private_key.pem 文件名 -pubout 输出 -out 到文件 rsa_public_key.pem 文件名
shell加解密
新建一个readme.txt 内容是taoshihan
使用公钥加密:
openssl rsautl -encrypt -in readme.txt -inkey rsa_public_key.pem -pubin -out hello.en
参数: rsautl 加解密 -encrypt 加密 -in 从文件输入 readme.txt 文件名 -inkey 输入的密钥 rsa_public_key.pem 上一步生成的公钥 -pubin 表名输入是公钥文件 -out输出到文件 hello.en 输出文件名
使用私钥解密:
openssl rsautl -decrypt -in hello.en -inkey rsa_private_key.pem -out hello.de
参数: -decrypt 解密 -in 从文件输入 hello.en 上一步生成的加密文件 -inkey 输入的密钥 rsa_private_key.pem 上一步生成的私钥 -out输出到文件 hello.de 输出的文件名
cat hello.de // taoshihan
php加解密
$profile="taoshihan"; echo "加密前:{$profile}\n"; //公钥加密 $public_key=file_get_contents("rsa_public_key.pem"); $pub_key = openssl_pkey_get_public($public_key); openssl_public_encrypt($profile,$encrypted,$pub_key); $encrypted=base64_encode($encrypted);//因为加密后是乱码,所以base64一下 echo "加密后:\n"; echo $encrypted."\n";//私钥解密 $private_key=file_get_contents("rsa_private_key.pem"); $pi_key = openssl_pkey_get_private($private_key); openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key); echo "解密后:\n"; echo $decrypted."\n";
新建rsa.php的文件
执行后结果:
加密前:taoshihan
加密后:
ShjsdlTceurVfO0ocENqHGl9RXrQRm3vuprqchhuVOdX1ldJC2O2sIvjjpQfPWOkF1WA+tqdyIl9YJQ0/2DqAp4zaqI1TCNsXduGn2iUZQ88g7B5eSI7r/iWKcX527pLe95EBvFMw/D65tlYscI5RClcp3KrOw2fqDQZ3D3nKAI=
解密后:
taoshihan
java加解密:
准备jar包 bcprov-ext-jdk15on-156.jar
wget http://www.bouncycastle.org/download/bcprov-ext-jdk15on-156.jar
RSAEncrypt.java 文件
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.security.KeyFactory; import java.security.interfaces.RSAPrivateKey; import java.security.spec.RSAPrivateKeySpec;import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException;import org.bouncycastle.jce.provider.BouncyCastleProvider;import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder;public class RSAEncrypt {/*** 私钥*/private RSAPrivateKey privateKey;/*** 公钥*/private RSAPublicKey publicKey;/*** 字节数据转字符串专用集合*/private static final char[] HEX_CHAR= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};/*** 获取私钥* @return 当前的私钥对象*/public RSAPrivateKey getPrivateKey() {return privateKey;}/*** 获取公钥* @return 当前的公钥对象*/public RSAPublicKey getPublicKey() {return publicKey;}/*** 随机生成密钥对*/public void genKeyPair(){KeyPairGenerator keyPairGen= null;try {keyPairGen= KeyPairGenerator.getInstance("RSA");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}keyPairGen.initialize(1024, new SecureRandom());KeyPair keyPair= keyPairGen.generateKeyPair();this.privateKey= (RSAPrivateKey) keyPair.getPrivate();this.publicKey= (RSAPublicKey) keyPair.getPublic();}/*** 从文件中输入流中加载公钥* @param in 公钥输入流* @throws Exception 加载公钥时产生的异常*/public void loadPublicKey(InputStream in) throws Exception{try {BufferedReader br= new BufferedReader(new InputStreamReader(in));String readLine= null;StringBuilder sb= new StringBuilder();while((readLine= br.readLine())!=null){if(readLine.charAt(0)=='-'){continue;}else{sb.append(readLine);sb.append('\r');}}loadPublicKey(sb.toString());} catch (IOException e) {throw new Exception("公钥数据流读取错误");} catch (NullPointerException e) {throw new Exception("公钥输入流为空");}}/*** 从字符串中加载公钥* @param publicKeyStr 公钥数据字符串* @throws Exception 加载公钥时产生的异常*/public void loadPublicKey(String publicKeyStr) throws Exception{try {BASE64Decoder base64Decoder= new BASE64Decoder();byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr);KeyFactory keyFactory= KeyFactory.getInstance("RSA");X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);} catch (NoSuchAlgorithmException e) {throw new Exception("无此算法");} catch (InvalidKeySpecException e) {throw new Exception("公钥非法");} catch (IOException e) {throw new Exception("公钥数据内容读取错误");} catch (NullPointerException e) {throw new Exception("公钥数据为空");}}/*** 从文件中加载私钥* @param keyFileName 私钥文件名* @return 是否成功* @throws Exception */public void loadPrivateKey(InputStream in) throws Exception{try {BufferedReader br= new BufferedReader(new InputStreamReader(in));String readLine= null;StringBuilder sb= new StringBuilder();while((readLine= br.readLine())!=null){if(readLine.charAt(0)=='-'){continue;}else{sb.append(readLine);sb.append('\r');}}loadPrivateKey(sb.toString());} catch (IOException e) {throw new Exception("私钥数据读取错误");} catch (NullPointerException e) {throw new Exception("私钥输入流为空");}}public void loadPrivateKey(String privateKeyStr) throws Exception{try {BASE64Decoder base64Decoder= new BASE64Decoder();byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr);RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(buffer));RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());KeyFactory keyFactory= KeyFactory.getInstance("RSA");RSAPrivateKey priKey=(RSAPrivateKey) keyFactory.generatePrivate(rsaPrivKeySpec);this.privateKey=priKey;// PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);// KeyFactory keyFactory= KeyFactory.getInstance("RSA");//this.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec);} catch (NoSuchAlgorithmException e) {throw new Exception("无此算法");} catch (InvalidKeySpecException e) {throw new Exception("私钥非法");} catch (IOException e) {throw new Exception("私钥数据内容读取错误");} catch (NullPointerException e) {throw new Exception("私钥数据为空");}}/*** 加密过程* @param publicKey 公钥* @param plainTextData 明文数据* @return* @throws Exception 加密过程中的异常信息*/public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{if(publicKey== null){throw new Exception("加密公钥为空, 请设置");}Cipher cipher= null;try {cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] output= cipher.doFinal(plainTextData);return output;} catch (NoSuchAlgorithmException e) {throw new Exception("无此加密算法");} catch (NoSuchPaddingException e) {e.printStackTrace();return null;}catch (InvalidKeyException e) {throw new Exception("加密公钥非法,请检查");} catch (IllegalBlockSizeException e) {throw new Exception("明文长度非法");} catch (BadPaddingException e) {throw new Exception("明文数据已损坏");}}/*** 解密过程* @param privateKey 私钥* @param cipherData 密文数据* @return 明文* @throws Exception 解密过程中的异常信息*/public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{if (privateKey== null){throw new Exception("解密私钥为空, 请设置");}Cipher cipher= null;try {cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] output= cipher.doFinal(cipherData);return output;} catch (NoSuchAlgorithmException e) {throw new Exception("无此解密算法");} catch (NoSuchPaddingException e) {e.printStackTrace();return null;}catch (InvalidKeyException e) {throw new Exception("解密私钥非法,请检查");} catch (IllegalBlockSizeException e) {throw new Exception("密文长度非法");} catch (BadPaddingException e) {throw new Exception("密文数据已损坏");} }/*** 字节数据转十六进制字符串* @param data 输入数据* @return 十六进制内容*/public static String byteArrayToString(byte[] data){StringBuilder stringBuilder= new StringBuilder();for (int i=0; i<data.length; i++){//取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]);//取出字节的低四位 作为索引得到相应的十六进制标识符stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);if (i<data.length-1){stringBuilder.append(' ');}}return stringBuilder.toString();}public static void main(String[] args){RSAEncrypt rsaEncrypt= new RSAEncrypt();//加载公钥try {rsaEncrypt.loadPublicKey(new FileInputStream("rsa_public_key.pem"));System.out.println("加载公钥成功");} catch (Exception e) {System.err.println(e.getMessage());System.err.println("加载公钥失败");}//加载私钥try {rsaEncrypt.loadPrivateKey(new FileInputStream("rsa_private_key.pem"));System.out.println("加载私钥成功");} catch (Exception e) {System.err.println(e.getMessage());System.err.println("加载私钥失败");}//测试字符串String encryptStr= "taoshihan";System.out.println("加密前:");System.out.println(encryptStr);try {//加密byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes());//解密byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);BASE64Encoder encode = new BASE64Encoder(); String buffer= encode.encode(cipher);System.out.println("加密后:");System.out.println(new String(buffer));System.out.println("解密后:");System.out.println(new String(plainText));} catch (Exception e) {System.err.println(e.getMessage());}} }
带包编译和执行
javac -cp bcprov-ext-jdk15on-156.jar RSAEncrypt.java java -cp .:bcprov-ext-jdk15on-156.jar RSAEncrypt
执行结果:
加载公钥成功 加载私钥成功 加密前: taoshihan 加密后: Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8 gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1 taQGBRDum/xEX6OsJ9I= 解密后: taoshihan
shell使用公钥加密,php使用私钥解密
shell:
openssl rsautl -encrypt -in readme.txt -inkey rsa_public_key.pem -pubin|base64加密后的字符串lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6 PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rOD UHxI+vDwQ+utRJRRo9U=
php:
<?php $encrypted="lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6 PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rOD UHxI+vDwQ+utRJRRo9U="; echo $encrypted."\n";//私钥解密 $private_key=file_get_contents("rsa_private_key.pem"); $pi_key = openssl_pkey_get_private($private_key); openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key); echo "解密后:\n"; echo $decrypted."\n";
执行结果:
lNJ50ODiofcp+adrtAI943HOsjdDTg3UMfUkt0NI7DhUjxCM+NAlBH08WVQRtYK9W8ZoQOta3QH6 PzmJT4WsI0yfNGiUWYgoYgSOtPURSQMbaCt3DM2Y5mEKqzbKLrhN+S+9Jrtmef1VuBUes8wN6rOD UHxI+vDwQ+utRJRRo9U= 解密后: taoshihan
java使用公钥加密,php解密:
拿上一步java生成的加密后字符串
<?php $encrypted="Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8 gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1 taQGBRDum/xEX6OsJ9I="; echo $encrypted."\n";//私钥解密 $private_key=file_get_contents("rsa_private_key.pem"); $pi_key = openssl_pkey_get_private($private_key); openssl_private_decrypt(base64_decode($encrypted),$decrypted,$pi_key); echo "解密后:\n"; echo $decrypted."\n";
执行结果:
Tt1p5XnamZkkVjGn1cVgEIb7U+CP27Xw93JQQUZyc2Up/rJL4Mx+dA8mxkva1a/I64sUTb7QD//8 gbss4bZY/DHrLityTt2/QjjQUFYD5/Aa1m1QKUBulWY4/C5so5dm6wrRnjolsIFUbY+RfH4B6hp1 taQGBRDum/xEX6OsJ9I= 解密后: taoshihan
转载于:https://www.cnblogs.com/taoshihan/p/6340854.html
[Linux] 使用openssl实现RSA非对称加密相关推荐
- php利用openssl实现RSA非对称加密签名
来源:http://www.webiji.com/archives/412 php利用openssl实现RSA非对称加密签名 1. 先用php生成一对公钥和私钥 $res = openssl_pkey ...
- php rsa验证签名,php利用openssl实现RSA非对称加密签名验证
1. 先用php生成一对公钥和私钥 $res = openssl_pkey_new(); openssl_pkey_export($res,$pri); $d= openssl_pkey_get_de ...
- CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互
(以下代码中都只做测试用,有些地方没有释放内存...这个自己解决下) 1.RSA非对称的,首先提供一个供测试用的证书和私钥的数据 1)pem格式的证书和私钥(公私钥是对应的)的base64编码 [cp ...
- Python代码实现MD5、AES对称加密和RSA非对称加密以及OpenSSl实践
1.MD5加密算法 1.1 MD5加密的特点 不可逆运算 对不同的数据加密的结果是定长的32位和16位字符(不管文件多大都一样) 对相同的数据加密,得到的结果是一样的(也就是复制). 抗修改性 :信息 ...
- JSON 接口如何实现 RSA 非对称加密与签名
代码地址如下: http://www.demodashi.com/demo/14000.html 一.概述 1. 数字签名的作用:保证数据完整性,机密性和发送方角色的不可抵赖性,加密与签字结合时,两套 ...
- Atitit RSA非对称加密原理与解决方案
Atitit RSA非对称加密原理与解决方案 1.1. 一.一点历史 1 1.2. 八.加密和解密 2 1.3. 二.基于RSA的消息传递机制 3 1.4. 基于rsa的授权验证机器码 4 1.5. ...
- java rsa 117_java实现RSA非对称加密解密
之前写过一篇java实现AES对称加密解密 在对密码加密传输的场景下 RSA非对称加密解密可能会更加适合. 原理就是后台生成一对公钥和私钥,公钥给前端用来加密,后台用私钥去解密,保证了传输过程中就算被 ...
- 前后端数据加密传输 RSA非对称加密
任务需求:要求登陆时将密码加密之后再进行传输到后端. 经过半天查询摸索折腾,于是有了如下成果: 加密方式:RSA非对称加密. 实现方式:公钥加密,私钥解密. 研究进度:javascript与java端 ...
- Springboot+RSA非对称加密
这是百度百科对(对称加密丶非对称加密)的解释: (1)对称加密算法在加密和解密时使用的是同一个秘钥. (2)非对称加密算法需要两个密钥来进行加密和解密,这两个秘钥是公开密钥(public key,简称 ...
最新文章
- bzoj 2119 股市的预测 —— 枚举关键点+后缀数组
- Java程序员从笨鸟到菜鸟之(一百零九)一步一步学习webservice(三)开发第一个基于XFire的webservice
- Boost:基于Boost的聊天的应用程序
- 语言语法糖_【c#】几种常用语法糖
- next_permutation算法(基于交换)
- 【牛客 - 283E】贪心只能过样例(模拟)
- cgdb 调试_在MacOS上使用gdb(cgdb)调试Golang程序
- 冠军方案解读,ICPR 2020 大规模商品图像识别挑战赛
- 7.22 C++自学笔记
- 为什么谷歌被骂上热搜一点也不冤,详解FLoC背后联邦计算
- 撞击测试软件,碰撞检测用什么软件?你会用Navisworks做碰撞检测吗?
- ajax 微信code获取_ajax实现微信网页授权登录
- webgate 重构 工作进度计划
- 关于stylebook样式调整的部分说明
- 使用Arduino+L298N控制光驱两项四线步进电机
- 机器学习-GB、GBDT、XGboost、Adaboost
- mysql 8.0 用户修改为简单密码
- Pluck 代码问题漏洞( CVE-2022-26965)
- k8s kubeadm 安装
- java indexeddb_indexedDB 基本使用
热门文章
- 一文攻破枚举类型-C语言
- 如何提高科研论文录用率?
- 计算机网络基础学测,《计算机网络技术基础》第二1章单元学习测习题-20210622072616.docx-原创力文档...
- 机器人学习--定位算法AMCL全局定位方案
- moldflow2018安装教程
- 虚拟机VMware 14安装教程
- 前后端分离时代,Java 程序员的变与不变!
- for循环10000次花多长时间_我的三菱FX PLC学习之子程序调用与循环
- 交换机短路_你了解交换机的相关知识吗?还不赶快收藏起来
- mxnet基础到提高(27)-Dense