jsencrypt代码分析——openssl的rsa加密解密在js的实现

 

在js上做rsa,感觉jsencrypt这个是封装的比较好的,但用起来还是遇到了些坑,所以踩进代码里填填坑~

项目在这里 https://github.com/travist/jsencrypt

【rsa算法】

首先科普一下rsa:公钥私钥成对,用其中一个加密只能用另一个解密,常用公钥加密私钥解密。

一开始看到斯坦佛那个库,原始的算法实现:

长度,建议至少1024。模数n(常取默认65537)两边都要用。

指数e,和n一起就是公钥。指数d,和n一起就是私钥。质数p和q用于生成密钥对,然后就丢弃不公开。

具体算法网上一大把,就不多说了。

【ssl/ssh密钥对】

用服务器上的工具生成的密钥对,格式一般是如下,有开始行结束行,内容用base64转码。这里涉及一些国际编码规范,代码分析时在逐一解释。

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIA4OVgB4FRq4l5zjEmd4r/jswRcHlZQ
kg10p9rzG3VyXCPpa/ZkwOYy+kGq7a7BjAKTpic2cUNRim4m8HKTdc8CAwEAAQ==
-----END PUBLIC KEY-----

【代码分析】

加载公钥:setPublicKey->setKey->JSEncryptRSAKey->parseKey

RSAKey.prototype.parseKey = function (pem) {...}

注释写得非常好!

/**
...省略...
 *This method accepts public key
* in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1).
* The format is defined as:
* PublicKeyInfo ::= SEQUENCE {
* algorithm AlgorithmIdentifier,
* PublicKey BIT STRING
* }
* Where AlgorithmIdentifier is:
* AlgorithmIdentifier ::= SEQUENCE {
* algorithm OBJECT IDENTIFIER, the OID of the enc algorithm
* parameters ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
* }
* and PublicKey is a SEQUENCE encapsulated in a BIT STRING
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/

代码如下:

 1 RSAKey.prototype.parseKey = function (pem) {
2 try {
3 ...
4 var der = reHex.test(pem) ? Hex.decode(pem) : Base64.unarmor(pem);
5 var asn1 = ASN1.decode(der);
6 ...
7 if (asn1.sub.length === 9) {
8 // Parse the private key.
9 }
10 else if (asn1.sub.length === 2) {
11 // Parse the public key.
12 var bit_string = asn1.sub[1];
13 var sequence = bit_string.sub[0];
14 modulus = sequence.sub[0].getHexStringValue();
15 this.n = parseBigInt(modulus, 16);
16 public_exponent = sequence.sub[1].getHexStringValue();
17 this.e = parseInt(public_exponent, 16);
18 }
19 else {
20 return false;
21 }
22 return true;
23 }
24 catch (ex) {
25 return false;
26 }
27 };

这里需要了解一下各种编码格式。hex和base64就不解释了。

ASN.1抽象语法标记,我的理解就是对数据进行结构化解析的规范:一个标准的ASN.1编码对象有四个域:对象标识域、数据长度域、数据域以及结束标志(可选,在长度不可知情况下需要,openssl中没有该标志)。

DER则是具体的编码实现。 http://baike.baidu.com/view/100318.htm#4

PKCS#1则是RSA中最基础的算法定义和密钥规定,讲人话就是定义了:公钥是元组(n,e),算法是n=q*p等一系列公式。https://en.wikipedia.org/wiki/PKCS1

这段代码两处亮点,一个是else if (asn1.sub.length === 2)判断公钥(没深究,反正靠子节点数判断);
两一个是var bit_string = asn1.sub[1];即前面有一段asn1.sub[0]是算法标识。

这里本身没有坑,但是生成公钥时如果命令不对应是会踩坑的(有一种命令是生成无算法标记的公钥)~~~

加密:encrypt->RSAEncrypt->pkcs1pad2 | doPublic->RSADoPublic

pkcs1pad2是做补位处理:

入参 var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3); 是(模位数+7)/8得到模的字节长度?

然后是一系列的移位操作,此处的作用是填入随机位使得每次加密的密文都不一样。http://blog.chinaunix.net/uid-21880738-id-1813144.html

RSADoPublic最终执行加密算法x^e (mod n)

至此,主要的算法、规范和坑基本上覆盖了,私钥和解密坑比较少,就不多说了。

最后,附送一个千年大坑,跨语言跨类库的时候不小心可能会遇到的 http://blog.chinaunix.net/uid-23069658-id-4282969.html

于这个js类库而言,-pubout出来的是可用的,而-RSAPublicKey_out出来的是不可用的。

与此对应,服务器openssl的类库中PEM_read_RSA_PUBKEY()读入是对应的,而PEM_read_RSAPublicKEY()读入是不对应的。

jsencrypt代码分析的更多相关文章

  1. jsencrypt代码分析——openssl的rsa加密解密在js的实现

    在js上做rsa,感觉jsencrypt这个是封装的比较好的,但用起来还是遇到了些坑,所以踩进代码里填填坑- 项目在这里 https://github.com/travist/jsencrypt [r ...

  2. Android代码分析工具lint学习

    1 lint简介 1.1 概述 lint是随Android SDK自带的一个静态代码分析工具.它用来对Android工程的源文件进行检查,找出在正确性.安全.性能.可使用性.可访问性及国际化等方面可能 ...

  3. pmd静态代码分析

    在正式进入测试之前,进行一定的静态代码分析及code review对代码质量及系统提高是有帮助的,以上为数据证明 Pmd 它是一个基于静态规则集的Java源码分析器,它可以识别出潜在的如下问题:– 可 ...

  4. [Asp.net 5] DependencyInjection项目代码分析-目录

    微软DI文章系列如下所示: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [ ...

  5. [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(5)(IEnumerable<>补充)

    Asp.net 5的依赖注入注入系列可以参考链接: [Asp.net 5] DependencyInjection项目代码分析-目录 我们在之前讲微软的实现时,对于OpenIEnumerableSer ...

  6. 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)

    构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...

  7. STM32启动代码分析 IAR 比较好

    stm32启动代码分析 (2012-06-12 09:43:31) 转载▼     最近开始使用ST的stm32w108芯片(也是一款zigbee芯片).开始看他的启动代码看的晕晕呼呼呼的. 还好在c ...

  8. 常用 Java 静态代码分析工具的分析与比较

    常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...

  9. SonarQube-5.6.3 代码分析平台搭建使用

    python代码分析 官网主页: http://docs.sonarqube.org/display/PLUG/Python+Plugin Windows下安装使用: 快速使用: 1.下载jdk ht ...

随机推荐

  1. android sqlite中判断某个表是否存在

    <span style="font-size:18px;">sqlite 中判断某个表是否存在的方法,贴出来供大家参考 /** * 判断某张表是否存在 * @param ...

  2. maven 纯注解一步一步搭建Spring Mvc项目(入门)

    初次接触spring MVC项目,通过一段时间的学习,本文介绍一种以纯注解的方法去配置spring MVC环境,让那些配置的.xml文件统统见鬼吧. 什么是Spring MVC Spring MVC属 ...

  3. 【转】Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)

    概要 前面,我们学完了List的全部内容(ArrayList, LinkedList, Vector, Stack). Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 Ja ...

  4. jQuery——类的添加与删除

    添加类:addClass 删除类:removeClass 判断类是否存在:hasClass <!DOCTYPE html> <html lang="en"> ...

  5. 关于Python中的类普通继承与super函数继承

    关于Python中的类普通继承与super函数继承 1.super只能用于新式类 2.多重继承super可以保公共父类仅被执行一次 一.首先看下普通继承的写法 二.再看看super继承的写法 参考链接 ...

  6. .mm c++ oc 混编

    When you create a static library you don't link in the dependent libraries. As a result, when you re ...

  7. appium 使用send_keys方法时报错: driver.find_element_by_id("com.hmkx.zgjkj:id/layout_search_bar_input").send_keys("123")

    新手 使用send_keys方法时一直报错,上网查这个方法的用法,看着大家都是这么写的啊,后来直接搜索 报错信息,搜索结果的针对性就清楚多了. 原来是seleium版本太高导致的问题. 可以先在cmd ...

  8. nginx设置绑定解析实现二级域名多域名

    apache(httpd)配置多个二级域名看这个链接:https://www.cnblogs.com/Crazy-Liu/p/10879928.html 网站的目录结构为/home/www├── bb ...

  9. yum仓库配置ftpx协议

    [root@localhost ~]# iptables -F[root@localhost ~]# systemctl stop firewalld[root@localhost ~]# syste ...

  10. 基于jquery的常见函数封装

    /// <reference path="jquery-1.8.0.min.js" />/** DIV或元素居中* @return*/jQuery.fn.mCenter ...