一篇学会RSA JavaScript加密,涉及OpenSSL

849 阅读7分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

正文

RSA加密是一种数据加密算法,广泛用于电子商业中,并且RSA算法是一种非对称加密算法。何为非对称算法呢?首先我们来了解下对称加密和非对称加密的概念。

对称加密

原文经过一把钥匙(密钥)加密后变成了密文,然后将密文传递给接收方,接收方再用这把钥匙(秘钥)解开密文。在这个过程中,其实加密和解密都是使用同一把钥匙,这种加密方式成为对称加密。

非对称加密

而非对称加密就是和对称加密相对,加密用的钥匙和解密所用的钥匙,并不是同一把钥匙。非对称加密首先会创建两把钥匙,而这两把钥匙是成对的分别称为公钥和私钥。在进行加密时我们使用公钥进行加密,而在解密的时候就必须要使用私钥才能进行解密,这就是非对称加密算法。

加密总结

  1. 对称加密由于使用了相同的秘钥,所以加解密快。但其秘钥需要在网络中传送,所以不大安全。
  2. 非对称加密使用的是秘钥对,即公钥、私钥。且知道其中一方,并不能破解出另一方,所以安全性高。但加解密耗时,速度慢。
  3. 解决的方法是将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。这也是https数据传输采用的方式。

了解了对称加密和非对称加密的概念,那JavaScript中如何实现非对称加密呢?下面看看解决方案

JSEncrypt框架

当浏览互联网寻找rsajavascript加密的好解决方案时,有大量的库基本上采用了Tom Wu@http://www cs students.stanford.edu/~tjw/jsbn/然后修改代码来做他们想做的事。但是,我找不到的是这个库的简单包装器,它基本上使用的是几乎没有接触过的库,但是添加了一个包装器来解析OpenSSL生成的实际私钥和公钥对。

上面这段话是npm中对该库的描述,下面看看如何使用,以及如何搭建OpenSSL环境创建公钥秘钥。

1. 用法

  1. 安装依赖
npm install jsencrypt --S
  1. 编写加解密工具方法
import JSEncrypt from 'jsencrypt/bin/jsencrypt'

// 公钥
const publicKey = '' 
// 私钥
const privateKey = ''  

// 加密
export function encrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey) // 设置公钥
  return encryptor.encrypt(txt) // 对数据进行加密
}

// 解密
export function decrypt(txt) {
  const encryptor = new JSEncrypt()
  encryptor.setPrivateKey(privateKey) // 设置私钥
  return encryptor.decrypt(txt) // 对数据进行解密
}

2. 秘钥对生成

简单点生成秘钥对,可借助现成的一些网站生成,比如:http://web.chacuo.net/netrsakeypair

当然我们这里玩点新鲜的,借助OpenSSL自己创建秘钥对,下面小节介绍。

OpenSSL

1. OpenSSL是什么?

SSL是Secure Sockets Layer(安全套接层协议)的缩写。

在计算机网络上,OpenSSL是一个开放源代码的软件库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连接者的身份。这个包广泛被应用在互联网的网页服务器上。

SSL能使用户/服务器应用之间的通信不被攻击者窃听,并且始终对服务器进行认证,还可选择对用户进行认证。SSL协议要求建立在可靠的传输层协议(TCP)之上。SSL协议的优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET等)能透明地建立于SSL协议之上。SSL协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。

SSL是利用公开密钥的加密技术(RSA)来作为用户端与服务器端在传送机密资料时的加密通讯协定。

OpenSSL采用C语言作为开发语言,这使得OpenSSL具有优秀的跨平台性。

OpenSSL整个软件包大概可以分成三个主要的功能部分:SSL协议库、应用程序以及密码算法库( 对称加密,如AES,非对称加密)。

OpenSSL一共实现了4种非对称加密算法,包括DH算法、RSA算法、DSA算法和椭圆曲线算法(EC) 。DH算法一般用于密钥交换。RSA算法既可以用于密钥交换,也可以用于数字签名,当然,如果你能够忍受其缓慢的速度,那么也可以用于数据加密。DSA算法则一般只用于数字签名。

OpenSSL实现了5种信息摘要算法,分别是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事实上包括了SHA和SHA1两种信息摘要算法。此外,OpenSSL还实现了DSS标准中规定的两种信息摘要算法DSS和DSS1。

OpenSSL其组成主要包括3个组件:

  • openssl:多用途的命令行工具
  • libcrypto:加密算法库
  • libssl:加密模块应用库,实现了ssl和tls

下面看看如何在window10上搭建OpenSSL环境,并验证基本功能。

2. 搭建OpenSSL环境

OpenSSL环境的搭建,网上找了很多教程,大多是要求去下载OpenSSL源码,然后用VS进行编译,但是看了那么长的编译步骤,太累人,因此找了个exe安装方法。

  1. 下载地址:win32/64_OpenSSL.exe下载地址
  2. 下载完成了,直接运行安装,点击next直至安装完成。这里要注意的是倘若OpenSSL安装路径的bin没有自动加入到操作系统的系统环境变量path中时,要手动去添加,路径例如:D:\OpenSSL-Win64\bin
  3. 直接cmd开启命令行窗口,然后输入运行指令:openssl,无报错,则安装成功

倘若报错:WARNING: can't open config file: /usr/local/ssl/openssl.cnf,则在当前窗口执行命令:

set OPENSSL_CONF=D:\OpenSSL-Win64\bin\openssl.cfg (路径为改为自己安装路径)

3. 生成秘钥对

  1. 生成私钥

openssl genrsa -out rsa_1024_priv.pem 1024

  1. 查看私钥

cat rsa_1024_priv.pem

  1. 根据私钥生成公钥

openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem

  1. 查看公钥

cat rsa_1024_pub.pem

这里生成的 rsa_1024_priv.pemrsa_1024_pub.pem 两文件对应的是私钥和秘钥,使用此秘钥对就能实现RSA JavaScript的加密了。

5. 扩展

openssl同时还可以实现对称加密、单向加密、生成密码、生成随机数、创建CA和申请证书,感兴趣的可以自行去了解。这里举个对称加密的例子:

对称加密需使用标准命令enc,用法如下:

openssl enc -ciphername [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a/-base64]
       [-A] [-k password] [-kfile filename] [-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md]
       [-p] [-P] [-bufsize number] [-nopad] [-debug] [-none] [-engine id]

常用选项有:

-in filename:指定要加密的文件存放路径

-out filename:指定加密后的文件存放路径

-salt:自动插入一个随机数作为文件内容加密,默认选项

-e:可以指明一种加密算法,若不指的话将使用默认加密算法

-d:解密,解密时也可以指定算法,若不指定则使用默认算法,但一定要与加密时的算法一致

-a/-base64:使用-base64位编码格式

示例: 加密:

openssl enc -e -des3 -a -salt -in fstab -out jiami 解密:

openssl enc -d -des3 -a -salt -in fstab -out jiami

总结

至此我们学习了对称加密和非对称加密的区别,在JavaScript如何实现非对称加密,以及如何通过搭建OpenSSL环境自主生成秘钥对。