Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Web Crypto API简介

Web Crypto API简介

原创
作者头像
王沛文
发布于 2018-07-31 07:43:34
发布于 2018-07-31 07:43:34
6.2K0
举报
文章被收录于专栏:王沛文的专栏王沛文的专栏

早年在web端做对称/非对称的加解密还是个很复杂的操作,由于没有js层面的基础库。很多基础设施只能从头开始。

QQ登录注册之前使用的RSA加密算法就是参考http://www-cs-students.stanford.edu/~tjw/jsbn/的实现。

还有各种aes/md5/sha等常用算法的js库也是层出不穷。但是由于大多都是个人项目,很多库并没有很好的维护,对于不同的算法支持也不是很完整。比如基于https://github.com/travist/jsencrypt就缺少RSA/OEAP的支持,https://github.com/ricmoo/aes-js也缺少AES/GCM的支持。

当然近些年来Web标准突飞猛进。对于常用密码学套件来说,最大的新增特性就是Web Crypto API了。

Web Crypto API提供了常用算法的加密/解密/签名/验证/摘要/key生成/协商等操作,功能上和nodejs中的crypto模块基本等同,也就是Web端的OpenSSL了。

但是由于接口和nodejs中的crypto不同,Web Crypto API统一采用的Promise来处理异步逻辑,而不是nodejs中的回调。这样可以很方便的使用await/async简化代码。

摘要算法

针对摘要算法提供的是disgest接口,这个接口可以提供SHA-1/SHA-256/SHA-384/SHA-512的摘要算法。

对于MD5等老旧的算法是不支持的。SHA-1这里也很特殊标准之前是规定支持这个算法,但是由于SHA-1本身存在缺陷,已经建议不使用,从浏览器来看就是移除SHA-1的支持。

代码语言:txt
AI代码解释
复制
window.crypto.subtle.digest(
    {
        name: "SHA-256",
    },
    new Uint8Array([1,2,3,4])
)
.then(function(hash){
    console.log(new Uint8Array(hash));
})
.catch(function(err){
    console.error(err);
});

这里比较特殊的就是接口的输入和输出都是ArrayBuffer相关的类

密钥操作

除了摘要算法之外,加解密签名都需要密钥来操作。涉及到的主要就是密钥生成/导入/导出。、

下面是生成密钥的示例代码

代码语言:txt
AI代码解释
复制
window.crypto.subtle.generateKey(
    {
        name: "RSASSA-PKCS1-v1_5",//算法名称
        hash: {name: "SHA-256"}, //签名时的hash算法
        //RSA参数
        modulusLength: 2048, //私钥长度
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        //EC参数
        namedCurve: "P-256",//曲线名字
        //AES参数
        length: 256, //密钥长度
    },
    false, //是否可以被导出
    ["sign", "verify"] //该key支持的操作
)
.then(function(key){
    //这里获取的key可以用于后续加解密签名等操作
    console.log(key);
})
.catch(function(err){
    console.error(err);
});

当然除了本地生成密钥还有导入外部密钥

代码语言:txt
AI代码解释
复制
window.crypto.subtle.importKey(
    "jwk", //密钥格式
    {   //密钥内容
        kty: "oct",
        k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
        alg: "A256CTR",
        ext: true,
    },
    {   //密钥算法
        name: "AES-CTR",
    },
    false, //是否能被导出
    ["encrypt", "decrypt"] //支持的操作模式
)

这里比较让人疑惑的就是密钥格式和密钥内容两个参数了

密钥格式和密钥内容

通常我们使用的密钥格式为PEM/DER。而上述例子中的jwk指的是JSON Web Key。具体可以参见rfc7517

对于常见的PEM格式我们需要使用其中有效内容部分。即BEGIN/END之间的部分所以我们可以将其中内容提取出来之后base64解码。

代码语言:txt
AI代码解释
复制
function convertPemToBinary(pem) {
    var lines = pem.split('\n')
    var encoded = ''
    for (var i = 0; i < lines.length; i++) {
        if (lines[i].trim().length > 0 &&
            !/-----BEGIN .*-----/.test(lines[i]) &&
            !/-----END .*-----/.test(lines[i])) {
            encoded += lines[i].trim()
        }
    }
    return base64StringToArrayBuffer(encoded)
}
function base64StringToArrayBuffer(b64str) {
    var byteStr = atob(b64str)
    var bytes = new Uint8Array(byteStr.length)
    for (var i = 0; i < byteStr.length; i++) {
        bytes[i] = byteStr.charCodeAt(i)
    }
    return bytes.buffer
}

DER格式则就是PEM中具体的内容。

对于EC/RSA公钥使用pkcs8的PEM/DER格式的实际数据配合密钥格式spki就可以导入了。

而私钥则是pkcs8格式的实际数据配合密钥格式pkcs8

对称密钥则可以通过raw加上实际密钥内容导入。

导出操作则相对简单

代码语言:txt
AI代码解释
复制
window.crypto.subtle.exportKey(
    "jwk", //密钥格式
    key //密钥
)
.then(function(keydata){
    console.log(keydata);
})
.catch(function(err){
    console.error(err);
});

加解密

代码语言:txt
AI代码解释
复制
window.crypto.subtle.encrypt(
    {
        name: "RSA-OAEP",
    },
    publicKey,
    data
)
.then(function(encrypted){
    console.log(new Uint8Array(encrypted));
})
.catch(function(err){
    console.error(err);
});

window.crypto.subtle.decrypt(
    {
        name: "RSA-OAEP",
    },
    privateKey,
    data
)
.then(function(decrypted){
    console.log(new Uint8Array(decrypted));
})
.catch(function(err){
    console.error(err);
});

加解密的接口都类似,输入算法/密钥/数据,输出结果。这里输入输出的数据也都是ArrayBuffer的格式

签名验签

代码语言:txt
AI代码解释
复制
window.crypto.subtle.sign(
    {
        name: "RSASSA-PKCS1-v1_5",
    },
    privateKey,
    data
)
.then(function(signature){
    console.log(new Uint8Array(signature));
})
.catch(function(err){
    console.error(err);
});

window.crypto.subtle.verify(
    {
        name: "RSASSA-PKCS1-v1_5",
    },
    publicKey,
    signature,
    data
)
.then(function(isvalid){
    console.log(isvalid);
})
.catch(function(err){
    console.error(err);
});

签名和验证签名的接口也是类似。

总结

Web Crypto API的入口是window.crypto.subtle

所有的接口都是window.crypto.subtle的方法。所有接口的返回都是Promise对象。

涉及密钥操作的算法需要先生成或导入密钥。导入密钥的格式有raw,spki,pkcs8,jwk。raw用于对称密钥直接导入的情况,spki则是DER格式的公钥,pkcs8时DER格式的pkcs8私钥,jwk则支持所有的场景,但是需要转换。

所有算法输入输出均为ArrayBuffer

补充

具体浏览器支持可以参见https://caniuse.com/#feat=cryptography

针对旧浏览器的polyfill/shim可以看https://github.com/vibornoff/webcrypto-shimhttps://github.com/PeculiarVentures/webcrypto-liner

常见的样例代码可以参见https://github.com/diafygi/webcrypto-examples

最后Web Crypto API由于属于安全接口,在非https的页面上可能不可用(chrome中)。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
编辑精选文章
换一批
使用 Nginx NJS 实现高性能的 RSA 加解密服务
在之前的文章《编写 Nginx 模块进行 RSA 加解密》中,我提到了如何编写 Nginx 模块,并借助 Nginx 实现相对高性能的加解密。正巧 Nginx 新版本发布,初步具备了原生“RSA加解密”能力。
soulteary
2021/11/25
2.2K0
使用 Nginx NJS 实现高性能的 RSA 加解密服务
Crypto算法库详解
Crypto 算法库在 python 中最初叫 pycrypto,这个作者有点懒,好几年没有更新,后来就有大佬写了个替代库 pycryptodome。这个库目前只支持 python3,安装也很简单pip install pycryptodome就行了!详细的用法可以看看 官方文档
py3study
2020/01/02
3.9K0
JavaScript高级程序设计-性能整理(三)
取得 WebGL 上下文后,就可以开始 3D 绘图了。如前所述,因为 WebGL 是 OpenGL ES 2.0 的 Web版,所以本节讨论的概念实际上是 JavaScript 所实现的 OpenGL 概念。可以在调用 getContext()取得 WebGL 上下文时指定一些选项。这些选项通过一个参数对象传入,选项就是参数对象的一个或多个属性。
草帽lufei
2022/07/29
2.2K0
鸿蒙开发:加密算法封装
加密算法是开发中常见的业务,为了安全起见,客户端与服务端传输数据,往往是通过加密之后进行通信,这样做的目的,可以保证数据的机密性,防止敏感数据泄露,而鸿蒙系统中,关于加密算法就比较容易实现,毕竟ArkTs是基于TypeScript实现的,所以有些算法之间基本是通用的。
程序员一鸣
2024/12/26
2090
鸿蒙开发:加密算法封装
HarmonyOS 开发实践——基于密钥库签名验签的用户认证
密钥库使用过程中除了用于加解密外,还用于程序访问控制认证和签名验签,常见的两个场景问题如下:
小帅聊鸿蒙
2024/11/23
1070
HarmonyOS 开发实践——基于密钥库签名验签的用户认证
如何在浏览器和nodejs中使用原生接口获得相同的hash?
在一些业务场景下,我们经常需要实现一些hash摘要来进行浏览器到服务端的验证逻辑,但是如果载入第三方库,我们又需要避免该库被攻击,而nodejs自带的crypto模块可以实现加密解密,却无法在浏览器端找到对等的实现。其实,浏览器端早就提供了 Web Crypto API,我们就可以利用浏览器原生的接口来实现摘要hash啦,这样无论是在性能上,还是安全性上,都是最优解。
否子戈
2023/09/02
3941
如何在浏览器和nodejs中使用原生接口获得相同的hash?
使用 openssl 生成证书(含openssl详解)
openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用、健壮、功能完备的工具套件,用以支持SSL/TLS 协议的实现。 官网:https://www.openssl.org/source/
菲宇
2019/06/12
16.9K0
使用 openssl 生成证书(含openssl详解)
openssl安装与使用
可以通过源码安装也可以apt-get install安装,安装openssl之前先看一下自己是否安装有openssl
全栈程序员站长
2022/07/22
4.6K0
openssl安装与使用
证书,密钥,加密,rsa到底是啥?
证书也叫CA(Certification Authority)证书;密钥就是用来加解密用的文件或者字符串;rsa即非对称加密算法。
老高的技术博客
2022/12/28
4.2K1
证书,密钥,加密,rsa到底是啥?
RSA签名的PSS模式
PSS 私钥签名流程的一种填充模式。目前主流的RSA签名包括RSA-PSS和RSA-PKCS#1 v1.5。
mariolu
2018/12/24
9.2K1
【每周一库】- JWT的Rust实现
支持RFC中的所有参数,但默认的标头只有typ和alg这两个集。在你需要设置kid参数或者更改算法时可以这样做:
MikeLoveRust
2020/08/21
2.3K0
Golang语言情怀-第66期 Go 语言标准库翻译 crypto/rsa
ErrDecryption代表解密数据失败。它故意写的语焉不详,以避免适应性攻击。
李海彬
2021/03/09
1.3K0
Data Encryption 你还在用NPM依赖吗?有 Crypto 就够了!
crypto是node.js中实现加密和解密的模块 在node.js中,使用OpenSSL类库作为内部实现加密解密的手段 OpenSSL是一个经过严格测试的可靠的加密与解密算法的实现工具
HoMeTown
2022/10/26
9160
Data Encryption 你还在用NPM依赖吗?有 Crypto 就够了!
Webman实战教程:使用JWT认证插件实现跨域安全认证
2、服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等等。
Tinywan
2023/10/22
1.3K1
Webman实战教程:使用JWT认证插件实现跨域安全认证
Android O中对TEE加解密算法的新要求
我们都知道,Android中keystore机制中的keymaster需要在TEE实现。Google关于Android后续版本中keymaster中的加解密算法要求如下: RSA 无填充 RSAES-OAEP (PaddingMode::RSA_OAEP) RSAES-PKCS1-v1_5 (PaddingMode::RSA_PKCS1_1_5_ENCRYPT) SHA-256 RSASSA-PSS (PaddingMode::RSA_PSS) RSASSA-PKCS1-v1_5 (PaddingMode:
安智客
2018/02/24
1.5K0
【爬虫知识】爬虫常见加密解密算法
本文总结了在爬虫中常见的各种加密算法、编码算法的原理、在 JavaScript 中和 Python 中的基本实现方法,遇到 JS 加密的时候可以快速还原加密过程,有的网站在加密的过程中可能还经过了其他处理,但是大致的方法是一样的。
K哥爬虫
2021/08/03
8.5K0
【爬虫知识】爬虫常见加密解密算法
Go加密算法总结
它是一种数据编码方式,虽然是可逆的,但是它的编码方式是公开的,无所谓加密。本文也对Base64编码方式做了简要介绍。
iginkgo18
2020/12/22
1.7K0
Koa基于NodeJS的WEB框架
Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。
码客说
2021/04/13
2.2K0
Koa基于NodeJS的WEB框架
RSA 证书加解密通信
经常有需要使用安全传输的场景,尤其是在一些泛及资金安全的行业,对数据的传输犹为重视安全性。 一般常用的就是对前参的数据进行加密,再到后台进行解密。 接口和接口之前的数据也用一样的方式进行加密和解密。
潇洒
2023/10/20
4590
RSA 证书加解密通信
再谈加密-RSA非对称加密的理解和使用
枕边书
2018/01/04
2.7K0
相关推荐
使用 Nginx NJS 实现高性能的 RSA 加解密服务
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档