sslopen RSA加解密
一、 原理概念
OpenSSL定义:
OpenSSL是为网络通信提供安全及数据完整性的一种安全协议,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。
OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。
作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。
功能:
基本功能
OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库、SSL协议库以及应用程序。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。
作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。
辅助功能
BIO机制是OpenSSL提供的一种高层IO接口,该接口封装了几乎所有类型的IO接口,如内存访问、文件访问以及Socket等。这使得代码的重用性大幅度提高,OpenSSL提供API的复杂性也降低了很多。
OpenSSL对于随机数的生成和管理也提供了一整套的解决方法和支持API函数。随机数的好坏是决定一个密钥是否安全的重要前提。
OpenSSL还提供了其它的一些辅助功能,如从口令生成密钥的API,证书签发和管理中的配置文件机制等等。如果你有足够的耐心,将会在深入使用OpenSSL的过程慢慢发现很多这样的小功能,让你不断有新的惊喜。
1.对称加密:
(1)甲方选择某一种加密规则,对信息进行加密;
(2)乙方使用同一种规则,对信息进行解密。
这种加密模式有一个最大弱点:甲方必须把加密规则告诉乙方,否则无法解密。保存和传递密钥,就成了最头疼的问题
2.非对称加密:
(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
(2)甲方获取乙方的公钥,然后用它对信息加密。
(3)乙方得到加密后的信息,用私钥解密。
如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。
公钥用于加密,私钥用于解密
二、 密钥生成步骤
RSA加密有如下几个步骤.
1. 生成公钥与私钥
2. 用公钥对需要加密的字符串等进行加密
3. 在需要解密的地方,用私钥进行解密
三、 流程及命令
- 首先使用OpenSSL生成私钥:openssl genrsa –out rsa_private_key.pem 1024
- 根据生成的私钥生成公钥:
- openssl rsa –in rsa_private_key.pem -out rsa_public_key.pem –pubout
writing RSA key
- 这时候的私钥还不能直接被使用,需要进行PKCS#8编码:
- openssl pkcs8 -topk8 -in rsa_private_key.pem -out
pkcs8_rsa_private_key.pem –nocrypt
注意:命令中指明了输入私钥文件为rsa_private_key.pem,输出私钥文件为pkcs8_rsa_private_key.pem,不采用任何二次加密(-nocrypt)
至此,可用的密钥对已经生成好了,私钥使用pkcs8_rsa_private_key.pem,公钥采用rsa_public_key.pem。
四、 Java
未进行抽出方法的代码:
package jdk_RSA; import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64; import javax.crypto.Cipher; public class JdkRsa {
//特别注意:RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行。
public static void main(String[] args) {
String str = "hello world!";
System.out.println(str.length());
// 初始化密钥
PublicKey keyPublic = null;
PrivateKey keyPrivate = null;
byte[] prikey = null;
byte[] pubkey = null;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
keyPublic = keyPair.getPublic();
keyPrivate = keyPair.getPrivate();
pubkey = keyPublic.getEncoded();
prikey = keyPrivate.getEncoded();
System.out.println("keyPublic:"+Base64.getEncoder().encodeToString(pubkey));
System.out.println("keyPrivate:"+Base64.getEncoder().encodeToString(prikey));
} catch (Exception e) {
e.printStackTrace();
}
// 此时的私密还不能用,需要通过PKCS8转换为RSAPrivateKey
RSAPrivateKey privateKey = null;
try {
KeyFactory factory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec pkcs8PrivateKey = new PKCS8EncodedKeySpec(prikey);
privateKey = (RSAPrivateKey) factory.generatePrivate(pkcs8PrivateKey);
System.out.println("转化为RSAPrivateKey的值:"+Base64.getEncoder().encodeToString(privateKey.getEncoded()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 通过x509转换公钥为RSAPublicKey
RSAPublicKey publicKey = null;
try {
KeyFactory factory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec x509PublicKey = new X509EncodedKeySpec(pubkey);
publicKey = (RSAPublicKey) factory.generatePublic(x509PublicKey);
System.out.println("转化为RSAPublicKey的值:"+Base64.getEncoder().encodeToString(privateKey.getEncoded()));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 通过Cipher对象进行加密——————公钥加密
String result = null;
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encodes = cipher.doFinal(str.getBytes());
result = Base64.getUrlEncoder().encodeToString(encodes);
System.out.println("公钥加密后的值:"+Base64.getUrlEncoder().encodeToString(encodes));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 通过Cipher对象进行加密—————私钥解密
try {
// 注意:这里是用base64解密后的字节数组
byte[] decoderData = Base64.getUrlDecoder().decode(result.getBytes());
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
System.out.println("要解密长度:"+result.getBytes().length);
int inputLen = decoderData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > 128) {
cache = cipher.doFinal(decoderData, offSet, 128);
} else {
cache = cipher.doFinal(decoderData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * 128;
}
byte[] decryptedData = out.toByteArray();
out.close();
System.out.println(Base64.getUrlEncoder().encodeToString(decryptedData).length());
System.out.println("私钥解密后的值:"+new String(decryptedData));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:
12
keyPublic:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqfHs1bBZgzgkCnKlxWEg1QLZfB+mIOH7TJ2Euew4t5gXzBDTSqXh36EPC2AzJqPRH6Eh6lcXWvRk9SV0jHuuq+yD3GxxV3sqdozYoRJIOCgmHWoXIbIqBPbefbbnNu3TeicAlZuytobit3bLSo8MZhS1tlv3Hfju/ZDiRWzGS+wIDAQAB
keyPrivate:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKp8ezVsFmDOCQKcqXFYSDVAtl8H6Yg4ftMnYS57Di3mBfMENNKpeHfoQ8LYDMmo9EfoSHqVxda9GT1JXSMe66r7IPcbHFXeyp2jNihEkg4KCYdahchsioE9t59tuc27dN6JwCVm7K2huK3dstKjwxmFLW2W/cd+O79kOJFbMZL7AgMBAAECgYArIs/x1mVbHQZ+mLDuss2iW7tJFDFsfA7q0j3uisgtqNO8h0XuP17xx9zNQekKZStZvlYIXjjuem4WaaedKUerUjJa6mktj5+lhRCbqnFjRk6Jw0QJlMAyE3AuRkauKJl121vHD+EzcSiWtT2LE9AsKLlTdAzsZ2RKvaYfaXBsYQJBAPZd5uMtP4FhHLU1wQr08KqSr8H0h1m8V05UFuslR/wZ5ACX/5Eoo7rqGDGuGY3B+4zZE1ZiCoyT1oKLLh+N/okCQQCxJwaC5sgsHTB0IO+nVXQ0DeQC8PWZJ2qBF7wo9faNP4Wne8llH3m7ZMWQiL9dJ/3QOnmaHVI6i5/b1AdxXgRjAkA2TTovxnBh5vK56jAzZwuIvS4qFOikWcPwis5GZAA6y8Yab2YwK4HzF9ffU11khmYYhFwjxRZIJ+m2+lBfOh/pAkEAg0tlLAdXPDq1+puegup2oU3aO8PSgpwP93Vb4w/Il48Iw8Se0u+tDRH2ytRO4AAPwRBVp78rfnCVHhvbGE6R+QJABLGkGvDaAe7LCIwjLweu+Z5jT6qCyLSOp/PcZkdQMXiRW4X8hZlZvl7+zW3lCcTUSq49NlWbN/mVSFGK7Dznwg==
转化为RSAPrivateKey的值:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKp8ezVsFmDOCQKcqXFYSDVAtl8H6Yg4ftMnYS57Di3mBfMENNKpeHfoQ8LYDMmo9EfoSHqVxda9GT1JXSMe66r7IPcbHFXeyp2jNihEkg4KCYdahchsioE9t59tuc27dN6JwCVm7K2huK3dstKjwxmFLW2W/cd+O79kOJFbMZL7AgMBAAECgYArIs/x1mVbHQZ+mLDuss2iW7tJFDFsfA7q0j3uisgtqNO8h0XuP17xx9zNQekKZStZvlYIXjjuem4WaaedKUerUjJa6mktj5+lhRCbqnFjRk6Jw0QJlMAyE3AuRkauKJl121vHD+EzcSiWtT2LE9AsKLlTdAzsZ2RKvaYfaXBsYQJBAPZd5uMtP4FhHLU1wQr08KqSr8H0h1m8V05UFuslR/wZ5ACX/5Eoo7rqGDGuGY3B+4zZE1ZiCoyT1oKLLh+N/okCQQCxJwaC5sgsHTB0IO+nVXQ0DeQC8PWZJ2qBF7wo9faNP4Wne8llH3m7ZMWQiL9dJ/3QOnmaHVI6i5/b1AdxXgRjAkA2TTovxnBh5vK56jAzZwuIvS4qFOikWcPwis5GZAA6y8Yab2YwK4HzF9ffU11khmYYhFwjxRZIJ+m2+lBfOh/pAkEAg0tlLAdXPDq1+puegup2oU3aO8PSgpwP93Vb4w/Il48Iw8Se0u+tDRH2ytRO4AAPwRBVp78rfnCVHhvbGE6R+QJABLGkGvDaAe7LCIwjLweu+Z5jT6qCyLSOp/PcZkdQMXiRW4X8hZlZvl7+zW3lCcTUSq49NlWbN/mVSFGK7Dznwg==
转化为RSAPublicKey的值:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKp8ezVsFmDOCQKcqXFYSDVAtl8H6Yg4ftMnYS57Di3mBfMENNKpeHfoQ8LYDMmo9EfoSHqVxda9GT1JXSMe66r7IPcbHFXeyp2jNihEkg4KCYdahchsioE9t59tuc27dN6JwCVm7K2huK3dstKjwxmFLW2W/cd+O79kOJFbMZL7AgMBAAECgYArIs/x1mVbHQZ+mLDuss2iW7tJFDFsfA7q0j3uisgtqNO8h0XuP17xx9zNQekKZStZvlYIXjjuem4WaaedKUerUjJa6mktj5+lhRCbqnFjRk6Jw0QJlMAyE3AuRkauKJl121vHD+EzcSiWtT2LE9AsKLlTdAzsZ2RKvaYfaXBsYQJBAPZd5uMtP4FhHLU1wQr08KqSr8H0h1m8V05UFuslR/wZ5ACX/5Eoo7rqGDGuGY3B+4zZE1ZiCoyT1oKLLh+N/okCQQCxJwaC5sgsHTB0IO+nVXQ0DeQC8PWZJ2qBF7wo9faNP4Wne8llH3m7ZMWQiL9dJ/3QOnmaHVI6i5/b1AdxXgRjAkA2TTovxnBh5vK56jAzZwuIvS4qFOikWcPwis5GZAA6y8Yab2YwK4HzF9ffU11khmYYhFwjxRZIJ+m2+lBfOh/pAkEAg0tlLAdXPDq1+puegup2oU3aO8PSgpwP93Vb4w/Il48Iw8Se0u+tDRH2ytRO4AAPwRBVp78rfnCVHhvbGE6R+QJABLGkGvDaAe7LCIwjLweu+Z5jT6qCyLSOp/PcZkdQMXiRW4X8hZlZvl7+zW3lCcTUSq49NlWbN/mVSFGK7Dznwg==
公钥加密后的值:Q7i6NzerRdcCSfSTO9yLDza9RE__-D-E_2APn-2QRXe3Yfr2tUsG5oq2PtK2f27-mTX0C6pKA3R3P_8pijhhyOwFO6eV8uJbnW0A0njKihYZUQJe-0-OiNcpLPOr_PtOgBFQh3bM7uBnclDRqeJKMBqQSmjQoDokiipePHmCccA=
要解密长度:172
16
私钥解密后的值:hello world!
抽出方法的代码
package jdk_RSA; import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64; import javax.crypto.Cipher; public class RSAjdk {
public static void main(String[] args) {
String content = "hello world!";
System.out.println(content.getBytes().length);
RSAjdk rsa = new RSAjdk();
KeyPair keyPair = rsa.genPairKey();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
RSAPrivateKey priKey = rsa.getPrivateKey(privateKey);
RSAPublicKey pubKey = rsa.getPublicKey(publicKey);
String encoderContent = rsa.enCoder(pubKey, content);
System.out.println("加密后的字符串:"+encoderContent);
String decoderContent = rsa.deCoder(priKey,encoderContent);
System.out.println("解密后的字符串:"+decoderContent);
} // 初始化密钥对儿,不用KeyPair也可以返回void
public KeyPair genPairKey() {
KeyPairGenerator keyPairGenerator = null;
try {
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 初始化生成的密钥对最大长度
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
return keyPair;
} // 取得私钥并经过Base64转化为RSAPrivateKey
public RSAPrivateKey getPrivateKey(PrivateKey privateKey) {
KeyFactory factory = null;
RSAPrivateKey priKey = null;
try {
factory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec pkcs8PrivateKey = new PKCS8EncodedKeySpec(privateKey.getEncoded());
priKey = (RSAPrivateKey) factory.generatePrivate(pkcs8PrivateKey);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return priKey;
} // 取得公钥并经过Base64转化为RSAPublicKey
public RSAPublicKey getPublicKey(PublicKey publicKey) {
KeyFactory factory = null;
RSAPublicKey pubKey = null;
try {
factory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec x509PublicKey = new X509EncodedKeySpec(publicKey.getEncoded());
pubKey = (RSAPublicKey) factory.generatePublic(x509PublicKey);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return pubKey;
} // 公钥加密
public String enCoder(RSAPublicKey key,String content) {
Cipher cipher = null;
byte[] encoderData = null;
String result = null;
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
encoderData = cipher.doFinal(content.getBytes());
result = Base64.getUrlEncoder().encodeToString(encoderData);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
// 私钥解密
public String deCoder(RSAPrivateKey key,String content) {
String result = null;
Cipher cipher;
byte[] decoderData = Base64.getUrlDecoder().decode(content.getBytes());
byte[] decoderedData = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
int end = decoderData.length;
byte[] cache = null;
int offset = 0;
int index = 0;
while(end - offset > 0) {
if(end - offset > 128) {
cache = cipher.doFinal(decoderData, offset, 128);
}else {
cache = cipher.doFinal(decoderData, offset, end-offset);
}
out.write(cache, 0, cache.length);
index++;
offset = index*128;
}
decoderedData = out.toByteArray();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(decoderedData!=null && decoderData.length!=0) {
result = new String(decoderedData);
}
return result;
}
}
运行结果:
12
加密后的字符串:m6RE8lEQYBw12u69lyYjxFkr6Lr4EuMv2fmezt7PY-Ty5nY8ld7bMnENodanPnr_b1iaAqm6YfCBUz3lF8ulOPKol8wUts9i1gV-vjMtJmDquWxiaTc7xzS4Z0uWZvAyLKAzTX2rxPjJi3WqqtjkkEkqOfYgwDMDRD-VCVEgN8c=
解密后的字符串:hello world!
sslopen RSA加解密的更多相关文章
- Rsa加解密Java、C#、php通用代码 密钥转换工具
之前发了一篇"TripleDes的加解密Java.C#.php通用代码",后面又有项目用到了Rsa加解密,还是在不同系统之间进行交互,Rsa在不同语言的密钥格式不一样,所以过程中主 ...
- 【go语言】RSA加解密
关于go语言的RSA加解密的介绍,这里有一篇文章,已经介绍的很完整了. 对应的go语言的加解密代码,参考git. 因为原文跨语言是跟php,我这里要跟c语言进行交互,所以,这里贴上c语言的例子. 参考 ...
- java RSA加解密以及用途
在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...
- openssl - rsa加解密例程
原文链接: http://www.cnblogs.com/cswuyg/p/3187462.html openssl是可以很方便加密解密的库,可以使用它来对需要在网络中传输的数据加密.可以使用非对称加 ...
- RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密
package com.geostar.gfstack.cas.util; import org.apache.commons.codec.binary.Base64; import javax.cr ...
- PHP RSA加解密详解(附代码)
前言:RSA加密一般用在涉及到重要数据时所使用的加密算法,比如用户的账户密码传输,订单的相关数据传输等. 加密方式说明:公钥加密,私钥解密.也可以 私钥加密,公钥解密 一.RSA简介 RSA公钥加密 ...
- RSA算法原理——(3)RSA加解密过程及公式论证
上期(RSA简介及基础数论知识)为大家介绍了:互质.欧拉函数.欧拉定理.模反元素 这四个数论的知识点,而这四个知识点是理解RSA加密算法的基石,忘了的同学可以快速的回顾一遍. 一.目前常见加密算法简介 ...
- 与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence
遇到的问题 在一个与Ruby语言对接的项目中,决定使用RSA算法来作为数据传输的加密与签名算法.但是,在使用Ruby生成后给我的私钥时,却发生了异常:IOException: algid parse ...
- JavaScript实现RSA加解密
在GitHub上找到jsencrypt.js对RSA加解密的工具文件,地址分别是:https://github.com/travist/jsencrypt和https://github.com/ope ...
随机推荐
- Ubuntu新手指引-软件包apt命令使用
看到这个博客,你十有八九是刚接触Ubuntu,不知从何下手.Ubuntu社区虽然现在不活跃,但里有很多文,可以帮助你快速上手,比如Ubuntu中文社区新手指引. 软件包的管理常常涉及root权限,普通 ...
- Jenkins 定时备份插件 ThinBackup
需求 公司的整个测试环境正式环境打包都是用的同一个Jenkins, 该Jenkins是搭建在内部的一台机器上,之前有一台机器的硬盘出了问题,为了安全起见,我们决定备份 Jenkins 的配置和数据. ...
- 前端学习 之 CSS(一)
一:什么是 CSS? ·CSS 指层叠样式表 (Cascading Style Sheets) ·样式定义如何显示 HTML 元素 ·样式通常存储在样式表中 ·把样式添加到 HTML 4.0 中,是为 ...
- git 从创建到推送到远程,到拉取,实操
https://www.liaoxuefeng.com/wiki/896043488029600/900003767775424 初始化 git init 添加所有文件到暂存区 git add . c ...
- ubuntu16.04下安装docker和docker-compose
开始安装 由于apt官方库里的docker版本可能比较旧,所以先卸载可能存在的旧版本:$ sudo apt-get remove docker docker-engine docker-ce dock ...
- android.view.WindowManager$BadTokenException 崩掉
问题: 以前的项目,今天打开运行,Activity刚打开的时候,点开一个弹窗是好的,但是再点到另一个界面的时候,返回,再点弹窗就崩了. 解决: 网上查了一下,发现出现这个问题的还特别多,大体如下: 1 ...
- iOS学习7:iOS沙盒(sandBox)机制(一)之获取沙盒路径及目录说明(转)
转:http://my.oschina.net/joanfen/blog/151145 一.iOS沙盒机制 iOS的应用只能访问为该应用创建的区域,不可访问其他区域,应用的其他非代码文件都存在此目录下 ...
- Django学习 之 HTTP与WEB为Django做准备
一.HTTP 1.HTTP 简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准. ...
- redis之常见操作
目录 redis的常见操作 1. redis客户端登录方式 2. 设置密码 3. 获取redis的配置 4. redis键(key) 语法 实例 Redis keys (黄色为重点) redis的常见 ...
- WebSocket 反爬虫
目录 WebSocket握手验证反爬虫 WebSocket 消息校验反爬虫 WebSocket Ping 反爬虫 总结 WebSocket握手验证反爬虫 ! HTTP协议 请求头 服务器端创建 soc ...