Java & PHP & Javascript 通用 RSA/ECB/PKCS1Padding 加密 解密 (长字符串)

系统与系统的数据交互中,有些敏感数据是不能直接明文传输的,所以在发送数据之前要进行加密,在接收到数据时进行解密处理;然而由于系统与系统之间的开发语言不同。

本次需求是生成二维码是通过java生成,由php来解密。基于这类需求所以选择了RSA进行加解密。

生成RSA公私钥分成三步生成,第1、2步可以满足php的使用,由于java的私钥要转化为PKCS8格式才能使用,所以执行第3步来实现。

还有一种加密方式参考: DES ECB 模式 JAVA PHP C# 实现 加密 解密 兼容 。

 

1、生成私钥

openssl genrsa -out rsa_private_key.pem 1024 

如下:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC6BSDlbRplhMMNZBKHX4xe8AwESpzHVfAcHHsX9FFSMuF91W3c
xgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKwko3tK9Ua691afod1lxORR3Ia
Z8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41GqvOw3G9leClSvjVnSwIDAQAB
AoGAagooYYCbTomq4wRL562ZCDmQsBWUX7Fmia/Wn6YfgVsN3bx/vx2Gld2AOIMB
ZVJXzzYGUYk7LV9bu/vKudRwWvtPIYzxPEOBoaFGPrEPTAfDVwOklhzTz3zDmCHi
hLSpjQXYCG7boZ6G96NfKyTRSGPqgovHY3+KJvd/gAoZqOkCQQDt9YXfanpuwZx1
7MYjMEvoh5UY1vSsV72ts3/gTVEUkWdfXHj0XhyRhOL9Qu99TGZcoEwecygoUPLm
dySyiXl/AkEAyB+JP8W7oTG/HTHc5QGDfwlPjIH1o5YG2I8Tp02i3G7OTJc/b9/+
SPxcKsT78xrgox5ModPKBX50F783Y2DANQJBAKY4Mjp882b4gWVybnlYHD4ir0h5
ptHYPFvgnfu9plx6sT3Qp4DzWHth2vlUT1w0CPC83E8M28lFula4dP7tvtsCQQCt
a2asdNVbophS3FrnuKAS/iaJRDVxRRk5oQMPACAZlYwAozC96gWZidb02S7cRHZV
5HPT6IwwppxD19hPrg/hAkBdnl+BGF/eRw80OHJtZBkLnY4Hx9YGft9AyIp3SB1z
QDhaWHgFA+8lED+bWTvJxt/IMmzyYBaGnZbEjCECKZLD
-----END RSA PRIVATE KEY-----

 

2、生成公钥

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

如下:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE
SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw
ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G
qvOw3G9leClSvjVnSwIDAQAB
-----END PUBLIC KEY-----

 

3、将RSA私钥转换成PKCS8格式

openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt > java_rsa_private_key.pem

如下:

-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALoFIOVtGmWEww1k
EodfjF7wDARKnMdV8Bwcexf0UVIy4X3VbdzGBP+Dmf6qUssXMITeFYb/Jfk0wDFH
iZLcyWHJcrCSje0r1Rrr3Vp+h3WXE5FHchpnydXu/kG/zLgkN7gTf9/9tAgbOuha
InSxdNw7jUaq87Dcb2V4KVK+NWdLAgMBAAECgYBqCihhgJtOiarjBEvnrZkIOZCw
FZRfsWaJr9afph+BWw3dvH+/HYaV3YA4gwFlUlfPNgZRiTstX1u7+8q51HBa+08h
jPE8Q4GhoUY+sQ9MB8NXA6SWHNPPfMOYIeKEtKmNBdgIbtuhnob3o18rJNFIY+qC
i8djf4om93+AChmo6QJBAO31hd9qem7BnHXsxiMwS+iHlRjW9KxXva2zf+BNURSR
Z19cePReHJGE4v1C731MZlygTB5zKChQ8uZ3JLKJeX8CQQDIH4k/xbuhMb8dMdzl
AYN/CU+MgfWjlgbYjxOnTaLcbs5Mlz9v3/5I/FwqxPvzGuCjHkyh08oFfnQXvzdj
YMA1AkEApjgyOnzzZviBZXJueVgcPiKvSHmm0dg8W+Cd+72mXHqxPdCngPNYe2Ha
+VRPXDQI8LzcTwzbyUW6Vrh0/u2+2wJBAK1rZqx01VuimFLcWue4oBL+JolENXFF
GTmhAw8AIBmVjACjML3qBZmJ1vTZLtxEdlXkc9PojDCmnEPX2E+uD+ECQF2eX4EY
X95HDzQ4cm1kGQudjgfH1gZ+30DIindIHXNAOFpYeAUD7yUQP5tZO8nG38gybPJg
FoadlsSMIQIpksM=
-----END PRIVATE KEY-----

或者在线工具:RSA,RSA2公钥私钥加密解密 或  RSA加密/解密在线工具

4.JAVA版本加解密:

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSAUtils {

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;

    public static final String SIGN_ALGORITHMS = "SHA256withRSA";

    private static String ALGORITHM_RSA = "RSA";

    /**
     * 使用公钥将数据加密
     * @param sourceData
     * @param publicKey
     * @return
     */
    public static String publicEncrypt(String sourceData, String publicKey){
        return rsaEncrypt(sourceData,publicKey,false);
    }

    /**
     * 使用私钥将数据加密
     * @param sourceData
     * @param privateKey
     * @return
     */
    public static String privateEncrypt(String sourceData, String privateKey){
        return rsaEncrypt(sourceData,privateKey,true);
    }


    /**
     * 使用公钥解密
     * @param encryptedData
     * @param privateKey
     * @return
     */
    public static String publicDecrypt(String encryptedData, String privateKey) {
        return rsaDecrypt(encryptedData,privateKey,false);
    }

    /**
     * 使用私钥解密
     * @param encryptedData
     * @param privateKey
     * @return
     */
    public static String privateDecrypt(String encryptedData, String privateKey) {
        return rsaDecrypt(encryptedData,privateKey,true);
    }

    protected static String rsaEncrypt(String sourceData, String key,boolean isPrivate){
        try {
            Key key1 = isPrivate ? loadPrivateKey(key) : loadPublicKey(key);
            byte[] data = sourceData.getBytes();
            byte[] dataReturn = new byte[0];
            Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
            cipher.init(Cipher.ENCRYPT_MODE, key1);

            // 加密时超过117字节就报错。为此采用分段加密的办法来加密
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) {
                byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,i + MAX_ENCRYPT_BLOCK));
                sb.append(new String(doFinal));
                dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
            }

            return Base64.encodeBase64URLSafeString(dataReturn);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    protected static String rsaDecrypt(String encryptedData, String key,boolean isPrivate){
        try {
            Key key1 = isPrivate ? loadPrivateKey(key) : loadPublicKey(key);
            byte[] data = Base64.decodeBase64(encryptedData);

            Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
            cipher.init(Cipher.DECRYPT_MODE, key1);

            // 解密时超过128字节就报错。为此采用分段解密的办法来解密
            byte[] dataReturn = new byte[0];
            for (int i = 0; i < data.length; i += MAX_DECRYPT_BLOCK) {
                byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_DECRYPT_BLOCK));
                dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
            }

            return new String(dataReturn);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 私钥加签名
     * @param encryptData
     * @param privateKey
     * @return
     */
    public static String rsaSign(String encryptData, String privateKey) {
        try {
            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
            signature.initSign(loadPrivateKey(privateKey));
            signature.update(encryptData.getBytes());
            byte[] signed = signature.sign();
            return Base64.encodeBase64URLSafeString(signed);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 公钥验签
     * @param encryptStr
     * @param sign
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static boolean verifySign(String encryptStr, String sign, String publicKey)throws Exception {
        try {
            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
            signature.initVerify(loadPublicKey(publicKey));
            signature.update(encryptStr.getBytes());
            return signature.verify(Base64.decodeBase64(sign));
        }  catch (NoSuchAlgorithmException e) {
            throw new Exception(String.format("验证数字签名时没有[%s]此类算法", SIGN_ALGORITHMS));
        } catch (InvalidKeyException e) {
            throw new Exception("验证数字签名时公钥无效");
        } catch (SignatureException e) {
            throw new Exception("验证数字签名时出现异常");
        }
    }

    public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
        byte[] buffer = Base64.decodeBase64(publicKeyStr);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
        return keyFactory.generatePublic(keySpec);
    }

    public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
        byte[] buffer = Base64.decodeBase64(privateKeyStr);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
        return keyFactory.generatePrivate(keySpec);
    }

    public  static String urlsafe_encode (String encryptStr){
        return encryptStr.replaceAll("\\+","-").replaceAll("/","_").replaceAll("=","").replaceAll("(\r\n|\r|\n|\n\r)","");

    }

    public  static String urlsafe_decode(String encryptStr){
        encryptStr= encryptStr.replaceAll("-","+").replaceAll("_","/");
        int mob = encryptStr.length()%4;
        if(mob>0){
            encryptStr+="====".substring(mob);
        }
        return encryptStr;
    }


    public  static  void main(String[ ] args) throws Exception {
        String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE" +
                "SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw" +
                "ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G" +
                "qvOw3G9leClSvjVnSwIDAQAB";
        String privateKeyStr = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALoFIOVtGmWEww1k" +
                "EodfjF7wDARKnMdV8Bwcexf0UVIy4X3VbdzGBP+Dmf6qUssXMITeFYb/Jfk0wDFH" +
                "iZLcyWHJcrCSje0r1Rrr3Vp+h3WXE5FHchpnydXu/kG/zLgkN7gTf9/9tAgbOuha" +
                "InSxdNw7jUaq87Dcb2V4KVK+NWdLAgMBAAECgYBqCihhgJtOiarjBEvnrZkIOZCw" +
                "FZRfsWaJr9afph+BWw3dvH+/HYaV3YA4gwFlUlfPNgZRiTstX1u7+8q51HBa+08h" +
                "jPE8Q4GhoUY+sQ9MB8NXA6SWHNPPfMOYIeKEtKmNBdgIbtuhnob3o18rJNFIY+qC" +
                "i8djf4om93+AChmo6QJBAO31hd9qem7BnHXsxiMwS+iHlRjW9KxXva2zf+BNURSR" +
                "Z19cePReHJGE4v1C731MZlygTB5zKChQ8uZ3JLKJeX8CQQDIH4k/xbuhMb8dMdzl" +
                "AYN/CU+MgfWjlgbYjxOnTaLcbs5Mlz9v3/5I/FwqxPvzGuCjHkyh08oFfnQXvzdj" +
                "YMA1AkEApjgyOnzzZviBZXJueVgcPiKvSHmm0dg8W+Cd+72mXHqxPdCngPNYe2Ha" +
                "+VRPXDQI8LzcTwzbyUW6Vrh0/u2+2wJBAK1rZqx01VuimFLcWue4oBL+JolENXFF" +
                "GTmhAw8AIBmVjACjML3qBZmJ1vTZLtxEdlXkc9PojDCmnEPX2E+uD+ECQF2eX4EY" +
                "X95HDzQ4cm1kGQudjgfH1gZ+30DIindIHXNAOFpYeAUD7yUQP5tZO8nG38gybPJg" +
                "FoadlsSMIQIpksM=";

        //加密
        String data = "i like java";
        String privateEncryptStr = RSAUtils.privateEncrypt(data, privateKeyStr);
        String publicEncryptStr = RSAUtils.publicEncrypt(data, publicKeyStr);
        String privateEncryptSign = RSAUtils.rsaSign(privateEncryptStr,privateKeyStr);
        String publicEncryptSign = RSAUtils.rsaSign(publicEncryptStr,privateKeyStr);

        System.out.println("source:" + data);
        System.out.println("private encryptStr: " + privateEncryptStr);
        System.out.println("public encryptStr: " + publicEncryptStr);
        System.out.println("private encrypt sign: " + privateEncryptSign);
        System.out.println("public encrypt sign: " + publicEncryptSign);
        System.out.println("public decrypt:" + RSAUtils.publicDecrypt(privateEncryptStr, publicKeyStr));
        System.out.println("private decrypt:" + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
        System.out.println("verifySign1: " + RSAUtils.verifySign(privateEncryptStr,privateEncryptSign,publicKeyStr));
        System.out.println("verifySign2: " + RSAUtils.verifySign(publicEncryptStr,publicEncryptSign,publicKeyStr));

        System.out.println("\r\n");
        publicEncryptStr = "WopnO2LnolZ7XpOwA_ktOhfkkaQQJQgkJudk3ZH_-ob36GQFv968nE1UBXxNekA9pIHBcvcl0ZWfwFhk-kyOF2FmQvpPY9LkqiCV0T32vhJet0n93ti2PBoFILxvChjzdOgSG9M0flH78Vm696Q4mHo7VMt_XMoHDTd3Rbagvt8";
        privateEncryptStr = "Fwb5BtLRveCWbx7FkXarl1zVOdwDvbDTl7gv-vPHXpj-T2wm9GlUDn3X0wnHHXkE8cqAT6PcE0g0ide6beP9_ysHMLgnC6wVqkomIKsi6C9TcGd4d6XQBjeJgdgccvDcD-7pcKrV9W-_Z7jkYkwwrjPGPd_uckEHR_cDXyOX4PU";
        System.out.println("php >>>> private decrypt: " + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
        System.out.println("php >>>> public decrypt: " + RSAUtils.publicDecrypt(privateEncryptStr, publicKeyStr));

        publicEncryptStr = "T2LFtY3dF_b6OBO07BN-3LtMSEBZqDukovDZ4HGCff8wosvlowf6IFJ3U7LFBIeHfiHBKiFuAV8-pFltCfTXtA4AwgVUnwbBMBWBfIJiLDi02ev30V-5BcYEuSF-cEdnSUd7WecrX4rHhzYLueGuj8H6c7RRbSbrJ6_3EFfU-K0";
        System.out.println("js >>>> private decrypt: " + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
        
        // 解密方式2
        PrivateKey privateKey = loadPrivateKey(privateKeyStr);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedText = cipher.doFinal(Base64.decodeBase64(publicEncryptStr));
        String decryptedString = new String(decryptedText);
        System.out.println("原文:" + plainText);
        System.out.println("解密后:" + decryptedString);
    }

}

输出如下:

source: i like java
private encryptStr: fHG5JMpTTF-KzrPCp827opRy3BvqmVIpIZS4gVuWqY5NeLsgoLxdrq3SaxUp_oBQ9pVqNlEiU9SIwbqJDjIqjHsCtVMOLoEdWicib_wCaoB16veKTEC4GnvviJwlS5IedH27oWGHKTTc6Ii5cLiQncjDAadvm0KCdC74yrwPqnc
public encryptStr: raoQQsfN0KBfPAMRWnxr9kFPvJ6BgQ7PRBCMnz0nWsH03sD4IdlMvKpj78BHe7V7Ga1HZHyDxuJhVaJ0T5qKl8qHXzvKquzNtdMru7G4X9o8ylzkGxJLg-HYCWOrsZ77ZMaKoV9p-TCf-yMI21OpL_5JGot-XNfVVPkmg0z9FW0
private encrypt sign: jlJvXY5t8KesDi3WaPr71jj2BigHLDr3b827Jl9xspbecdUjPB44Xe3sjWnzvFDLpKJGiNTvqE-Qyu3FZpG_NyI5yhVrAQgZmyYfVywmeDDsTOQYk1xP0UEfFgB0MXsFdlfSdMu5JcR5kgC5Xl5jds1b0Z2Nq7gQ-bvFJQcuHgU
public encrypt sign: ngN2kQppfITyn5yAfNc1c-ofK20trKJWXIjlaJhWtm7s2jzv5rcsPY5JH06CMAIIbnKGIUcoVvMeKavAIVFb4G_h3CvXIYnxMjQL19Op-SbtyGNwT-rZzTEP8tKfxFRVm7SrHHDz2s287S3vqQz9vGEGNmgDHEdrCfHBmmoFkQA
public decrypt: i like java
private decrypt: i like java
verifySign1: true
verifySign2: true
 

php >>>> private decrypt: i like php
php >>>> public decrypt: i like php

js >>>> private decrypt: i like JS

 

5.Golang版本加解密

package chiper

import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "errors"
    "fmt"
    "testing"
)

var privateKey = `
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC6BSDlbRplhMMNZBKHX4xe8AwESpzHVfAcHHsX9FFSMuF91W3c
xgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKwko3tK9Ua691afod1lxORR3Ia
Z8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41GqvOw3G9leClSvjVnSwIDAQAB
AoGAagooYYCbTomq4wRL562ZCDmQsBWUX7Fmia/Wn6YfgVsN3bx/vx2Gld2AOIMB
ZVJXzzYGUYk7LV9bu/vKudRwWvtPIYzxPEOBoaFGPrEPTAfDVwOklhzTz3zDmCHi
hLSpjQXYCG7boZ6G96NfKyTRSGPqgovHY3+KJvd/gAoZqOkCQQDt9YXfanpuwZx1
7MYjMEvoh5UY1vSsV72ts3/gTVEUkWdfXHj0XhyRhOL9Qu99TGZcoEwecygoUPLm
dySyiXl/AkEAyB+JP8W7oTG/HTHc5QGDfwlPjIH1o5YG2I8Tp02i3G7OTJc/b9/+
SPxcKsT78xrgox5ModPKBX50F783Y2DANQJBAKY4Mjp882b4gWVybnlYHD4ir0h5
ptHYPFvgnfu9plx6sT3Qp4DzWHth2vlUT1w0CPC83E8M28lFula4dP7tvtsCQQCt
a2asdNVbophS3FrnuKAS/iaJRDVxRRk5oQMPACAZlYwAozC96gWZidb02S7cRHZV
5HPT6IwwppxD19hPrg/hAkBdnl+BGF/eRw80OHJtZBkLnY4Hx9YGft9AyIp3SB1z
QDhaWHgFA+8lED+bWTvJxt/IMmzyYBaGnZbEjCECKZLD
-----END RSA PRIVATE KEY-----
`

var publicKey = `
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE
SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw
ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G
qvOw3G9leClSvjVnSwIDAQAB
-----END PUBLIC KEY-----
`

// RsaBase64Encrypt 加密
func RsaBase64Encrypt(publicKey string, sourceData string) (string, error) {
    encryptData, err := RsaEncrypt(publicKey, []byte(sourceData))
    if nil != err {
        return "", err
    }
    return base64.RawURLEncoding.EncodeToString(encryptData), nil
}

// RsaEncrypt 加密
func RsaEncrypt(publicKey string, sourceData []byte) ([]byte, error) {
    //解密pem格式的公钥
    block, _ := pem.Decode([]byte(publicKey))
    if block == nil {
        return nil, errors.New("public key error")
    }
    // 解析公钥
    pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    // 类型断言
    pubic := pubInterface.(*rsa.PublicKey)
    //加密
    return rsa.EncryptPKCS1v15(rand.Reader, pubic, sourceData)
}

// RsaBase64Decrypt 解密
func RsaBase64Decrypt(privateKey string, base64Str string) (string, error) {
    //base64解密
    encrypted, err := base64.RawURLEncoding.DecodeString(base64Str)
    if nil != err {
        return "", err
    }

    sourceData, err := RsaDecrypt(privateKey, encrypted)
    if nil != err {
        return "", err
    }
    return string(sourceData), nil
}

// RsaDecrypt 解密
func RsaDecrypt(privateKey string, encryptedData []byte) ([]byte, error) {
    //解密
    block, _ := pem.Decode([]byte(privateKey))
    if block == nil {
        return nil, errors.New("private key error")
    }
    //解析PKCS1格式的私钥
    private, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    // 解密
    return rsa.DecryptPKCS1v15(rand.Reader, private, encryptedData)
}

func TestRsaBase64Decrypt(t *testing.T) {
    cipherTxt, _ := RsaBase64Encrypt(publicKey, "i like golang")
    fmt.Println(fmt.Sprintf("cipherTxt: %s", cipherTxt))

    golang, _ := RsaBase64Decrypt(privateKey, cipherTxt)
    fmt.Println(fmt.Sprintf("txt: %s", golang))

    cipherTxt = "raoQQsfN0KBfPAMRWnxr9kFPvJ6BgQ7PRBCMnz0nWsH03sD4IdlMvKpj78BHe7V7Ga1HZHyDxuJhVaJ0T5qKl8qHXzvKquzNtdMru7G4X9o8ylzkGxJLg-HYCWOrsZ77ZMaKoV9p-TCf-yMI21OpL_5JGot-XNfVVPkmg0z9FW0"
    java, _ := RsaBase64Decrypt(privateKey, cipherTxt)
    fmt.Println(fmt.Sprintf("txt: %s", java))

    cipherTxt = "WopnO2LnolZ7XpOwA_ktOhfkkaQQJQgkJudk3ZH_-ob36GQFv968nE1UBXxNekA9pIHBcvcl0ZWfwFhk-kyOF2FmQvpPY9LkqiCV0T32vhJet0n93ti2PBoFILxvChjzdOgSG9M0flH78Vm696Q4mHo7VMt_XMoHDTd3Rbagvt8"
    php, _ := RsaBase64Decrypt(privateKey, cipherTxt)
    fmt.Println(fmt.Sprintf("txt: %s", php))

    cipherTxt = "T2LFtY3dF_b6OBO07BN-3LtMSEBZqDukovDZ4HGCff8wosvlowf6IFJ3U7LFBIeHfiHBKiFuAV8-pFltCfTXtA4AwgVUnwbBMBWBfIJiLDi02ev30V-5BcYEuSF-cEdnSUd7WecrX4rHhzYLueGuj8H6c7RRbSbrJ6_3EFfU-K0"
    js, _ := RsaBase64Decrypt(privateKey, cipherTxt)
    fmt.Println(fmt.Sprintf("txt: %s", js))
}

输出如下:

=== RUN   TestRsaBase64Decrypt
cipherTxt: LWxejL0MIDpDCbf3rZu1PpEEPe7FsnWfe2u1ZO41JcGsSvKD1x2hulWyYyRVJ1s1oLx_tWUXNTEOO6s8BSalgmLSAWaFsJsThLECVJAMnToho9siYKIqdskDLz7A0y3tpYUPXr-_tv_mcKkCQrBAIhSVwdfocsyZ7r1nD4Pc_mQ
txt: i like golang
txt: i like java
txt: i like php
txt: i like JS
--- PASS: TestRsaBase64Decrypt (0.02s)
PASS

 

6.PHP版本加解密

<?php

$private_key = <<<KEY
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC6BSDlbRplhMMNZBKHX4xe8AwESpzHVfAcHHsX9FFSMuF91W3c
xgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKwko3tK9Ua691afod1lxORR3Ia
Z8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41GqvOw3G9leClSvjVnSwIDAQAB
AoGAagooYYCbTomq4wRL562ZCDmQsBWUX7Fmia/Wn6YfgVsN3bx/vx2Gld2AOIMB
ZVJXzzYGUYk7LV9bu/vKudRwWvtPIYzxPEOBoaFGPrEPTAfDVwOklhzTz3zDmCHi
hLSpjQXYCG7boZ6G96NfKyTRSGPqgovHY3+KJvd/gAoZqOkCQQDt9YXfanpuwZx1
7MYjMEvoh5UY1vSsV72ts3/gTVEUkWdfXHj0XhyRhOL9Qu99TGZcoEwecygoUPLm
dySyiXl/AkEAyB+JP8W7oTG/HTHc5QGDfwlPjIH1o5YG2I8Tp02i3G7OTJc/b9/+
SPxcKsT78xrgox5ModPKBX50F783Y2DANQJBAKY4Mjp882b4gWVybnlYHD4ir0h5
ptHYPFvgnfu9plx6sT3Qp4DzWHth2vlUT1w0CPC83E8M28lFula4dP7tvtsCQQCt
a2asdNVbophS3FrnuKAS/iaJRDVxRRk5oQMPACAZlYwAozC96gWZidb02S7cRHZV
5HPT6IwwppxD19hPrg/hAkBdnl+BGF/eRw80OHJtZBkLnY4Hx9YGft9AyIp3SB1z
QDhaWHgFA+8lED+bWTvJxt/IMmzyYBaGnZbEjCECKZLD
-----END RSA PRIVATE KEY-----
KEY;

$private8_key = <<<KEY
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALoFIOVtGmWEww1k
EodfjF7wDARKnMdV8Bwcexf0UVIy4X3VbdzGBP+Dmf6qUssXMITeFYb/Jfk0wDFH
iZLcyWHJcrCSje0r1Rrr3Vp+h3WXE5FHchpnydXu/kG/zLgkN7gTf9/9tAgbOuha
InSxdNw7jUaq87Dcb2V4KVK+NWdLAgMBAAECgYBqCihhgJtOiarjBEvnrZkIOZCw
FZRfsWaJr9afph+BWw3dvH+/HYaV3YA4gwFlUlfPNgZRiTstX1u7+8q51HBa+08h
jPE8Q4GhoUY+sQ9MB8NXA6SWHNPPfMOYIeKEtKmNBdgIbtuhnob3o18rJNFIY+qC
i8djf4om93+AChmo6QJBAO31hd9qem7BnHXsxiMwS+iHlRjW9KxXva2zf+BNURSR
Z19cePReHJGE4v1C731MZlygTB5zKChQ8uZ3JLKJeX8CQQDIH4k/xbuhMb8dMdzl
AYN/CU+MgfWjlgbYjxOnTaLcbs5Mlz9v3/5I/FwqxPvzGuCjHkyh08oFfnQXvzdj
YMA1AkEApjgyOnzzZviBZXJueVgcPiKvSHmm0dg8W+Cd+72mXHqxPdCngPNYe2Ha
+VRPXDQI8LzcTwzbyUW6Vrh0/u2+2wJBAK1rZqx01VuimFLcWue4oBL+JolENXFF
GTmhAw8AIBmVjACjML3qBZmJ1vTZLtxEdlXkc9PojDCmnEPX2E+uD+ECQF2eX4EY
X95HDzQ4cm1kGQudjgfH1gZ+30DIindIHXNAOFpYeAUD7yUQP5tZO8nG38gybPJg
FoadlsSMIQIpksM=
-----END PRIVATE KEY-----
KEY;

$public_key = <<<KEY
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE
SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw
ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G
qvOw3G9leClSvjVnSwIDAQAB
-----END PUBLIC KEY-----
KEY;

$data = 'i like php';
//使用公钥将数据加密
$encrypt_data = RsaUtils::publicEncrypt($data,$public_key);
//使用私钥将数据解密
$decrypt_data = RsaUtils::privateDecrypt($encrypt_data,$private_key);

echo 'public encrypt data:'.$encrypt_data.PHP_EOL;
echo 'private decrypt data:'.$decrypt_data.PHP_EOL;


//使用私钥将数据加密
$encrypt_data = RsaUtils::privateEncrypt($data,$private_key);
//使用私钥将加密数据加签
$private_encrypt_sign = RsaUtils::rsaSign($encrypt_data,$private_key);
//使用公钥解签
$public_check_sign = RsaUtils::verifySign($encrypt_data,$private_encrypt_sign,$public_key);
//使用公钥将数据解密
$decrypt_data = RsaUtils::publicDecrypt($encrypt_data,$public_key);

echo 'private encrypt data: '.$encrypt_data.PHP_EOL;
echo 'private encrypt sign: '.$private_encrypt_sign.PHP_EOL;
echo 'public check sign: '.$public_check_sign.PHP_EOL;
echo 'public decrypt data: '.$decrypt_data.PHP_EOL;



//验证java加密解密方法
$private_encrypt_data = 'fHG5JMpTTF-KzrPCp827opRy3BvqmVIpIZS4gVuWqY5NeLsgoLxdrq3SaxUp_oBQ9pVqNlEiU9SIwbqJDjIqjHsCtVMOLoEdWicib_wCaoB16veKTEC4GnvviJwlS5IedH27oWGHKTTc6Ii5cLiQncjDAadvm0KCdC74yrwPqnc';
$public_decrypt_data = RsaUtils::publicDecrypt($private_encrypt_data,$public_key);
$sign_data1 = 'jlJvXY5t8KesDi3WaPr71jj2BigHLDr3b827Jl9xspbecdUjPB44Xe3sjWnzvFDLpKJGiNTvqE-Qyu3FZpG_NyI5yhVrAQgZmyYfVywmeDDsTOQYk1xP0UEfFgB0MXsFdlfSdMu5JcR5kgC5Xl5jds1b0Z2Nq7gQ-bvFJQcuHgU';
$verify_sign1 = RsaUtils::verifySign($private_encrypt_data,$sign_data1,$public_key);

$public_encrypt_data = 'raoQQsfN0KBfPAMRWnxr9kFPvJ6BgQ7PRBCMnz0nWsH03sD4IdlMvKpj78BHe7V7Ga1HZHyDxuJhVaJ0T5qKl8qHXzvKquzNtdMru7G4X9o8ylzkGxJLg-HYCWOrsZ77ZMaKoV9p-TCf-yMI21OpL_5JGot-XNfVVPkmg0z9FW0';
$private_decrypt_data = RsaUtils::privateDecrypt($public_encrypt_data, $private_key);
$sign_data2 = 'ngN2kQppfITyn5yAfNc1c-ofK20trKJWXIjlaJhWtm7s2jzv5rcsPY5JH06CMAIIbnKGIUcoVvMeKavAIVFb4G_h3CvXIYnxMjQL19Op-SbtyGNwT-rZzTEP8tKfxFRVm7SrHHDz2s287S3vqQz9vGEGNmgDHEdrCfHBmmoFkQA';
$verify_sign2 = RsaUtils::verifySign($public_encrypt_data,$sign_data2,$public_key);

echo PHP_EOL;
echo 'public_decrypt_data: '.$public_decrypt_data.PHP_EOL;
echo 'verifySign1: '. $verify_sign1.PHP_EOL;

echo 'private_decrypt_data: '.$private_decrypt_data.PHP_EOL;
echo 'verifySign2: '. $verify_sign2.PHP_EOL;

$public_encrypt_data = 'T2LFtY3dF_b6OBO07BN-3LtMSEBZqDukovDZ4HGCff8wosvlowf6IFJ3U7LFBIeHfiHBKiFuAV8-pFltCfTXtA4AwgVUnwbBMBWBfIJiLDi02ev30V-5BcYEuSF-cEdnSUd7WecrX4rHhzYLueGuj8H6c7RRbSbrJ6_3EFfU-K0';
$private_decrypt_data = RsaUtils::privateDecrypt($public_encrypt_data,$private_key);
echo PHP_EOL;
echo 'private_decrypt_data: '.$private_decrypt_data.PHP_EOL;



class RsaUtils{

    /**
     * 签名算法,SHA256WithRSA
     */
    private const SIGNATURE_ALGORITHM = OPENSSL_ALGO_SHA256;

    /**
     * RSA最大加密明文大小
     */
    private const MAX_ENCRYPT_BLOCK = 117;

    /**
     * RSA最大解密密文大小
     */
    private const MAX_DECRYPT_BLOCK = 128;

    /**
     * 使用公钥将数据加密
     * @param $data string 需要加密的数据
     * @param $publicKey string 公钥
     * @return string 返回加密串(base64编码)
     */
    public static function publicEncrypt($data,$publicKey){
        $data = str_split($data, self::MAX_ENCRYPT_BLOCK);

        $encrypted = '';
        foreach($data as & $chunk){
            if(!openssl_public_encrypt($chunk, $encryptData, $publicKey)){
                return '';
            }else{
                $encrypted .= $encryptData;
            }
        }
        return self::urlSafeBase64encode($encrypted);
    }

    /**
     * 使用私钥解密
     * @param $data string 需要解密的数据
     * @param $privateKey string 私钥
     * @return string 返回解密串
     */
    public static function privateDecrypt($data,$privateKey){
        $data = str_split(self::urlSafeBase64decode($data), self::MAX_DECRYPT_BLOCK);

        $decrypted = '';
        foreach($data as & $chunk){
            if(!openssl_private_decrypt($chunk, $decryptData, $privateKey)){
                return '';
            }else{
                $decrypted .= $decryptData;
            }
        }
        return $decrypted;
    }

    /**
     * 使用私钥将数据加密
     * @param $data string 需要加密的数据
     * @param $privateKey string 私钥
     * @return string 返回加密串(base64编码)
     */
    public static function privateEncrypt($data,$privateKey){
        $data = str_split($data, self::MAX_ENCRYPT_BLOCK);

        $encrypted = '';
        foreach($data as & $chunk){
            if(!openssl_private_encrypt($chunk, $encryptData, $privateKey)){
                return '';
            }else{
                $encrypted .= $encryptData;
            }
        }
        return self::urlSafeBase64encode($encrypted);
    }


    /**
     * 使用公钥解密
     * @param $data string 需要解密的数据
     * @param $publicKey string 公钥
     * @return string 返回解密串
     */
    public static function publicDecrypt($data,$publicKey){
        $data = str_split(self::urlSafeBase64decode($data), self::MAX_DECRYPT_BLOCK);

        $decrypted = '';
        foreach($data as & $chunk){
            if(!openssl_public_decrypt($chunk, $decryptData, $publicKey)){
                return '';
            }else{
                $decrypted .= $decryptData;
            }
        }
        return $decrypted;
    }


    /**
     * 私钥加签名
     * @param $data 被加签数据
     * @param $privateKey 私钥
     * @return mixed|string
     */
    public static function rsaSign($data, $privateKey){
        if(openssl_sign($data, $sign, $privateKey, self::SIGNATURE_ALGORITHM)){
            return self::urlSafeBase64encode($sign);
        }
        return '';
    }

    /**
     * 公钥验签
     * @param $data 被加签数据
     * @param $sign 签名
     * @param $publicKey 公钥
     * @return bool
     */
    public static function verifySign($data, $sign, $publicKey):bool {
        return (1 == openssl_verify($data, self::urlSafeBase64decode($sign), $publicKey, self::SIGNATURE_ALGORITHM));
    }

    /**
     * url base64编码
     * @param $string
     * @return mixed|string
     */
    public static function urlSafeBase64encode($string){
        $data = str_replace(array('+','/','='), array( '-','_',''), base64_encode($string));
        return $data;
    }

    /**
     * url base64解码
     * @param $string
     * @return bool|string
     */
    public static function urlSafeBase64decode($string){
        $data = str_replace(array('-','_'), array('+','/'), $string);
        $mod4 = strlen($data) % 4;
        if($mod4){
            $data .= substr('====', $mod4);
        }
        return base64_decode($data);
    }
}

输出如下:

public encrypt data: WopnO2LnolZ7XpOwA_ktOhfkkaQQJQgkJudk3ZH_-ob36GQFv968nE1UBXxNekA9pIHBcvcl0ZWfwFhk-kyOF2FmQvpPY9LkqiCV0T32vhJet0n93ti2PBoFILxvChjzdOgSG9M0flH78Vm696Q4mHo7VMt_XMoHDTd3Rbagvt8
private decrypt data: i like php
public encrypt data: Fwb5BtLRveCWbx7FkXarl1zVOdwDvbDTl7gv-vPHXpj-T2wm9GlUDn3X0wnHHXkE8cqAT6PcE0g0ide6beP9_ysHMLgnC6wVqkomIKsi6C9TcGd4d6XQBjeJgdgccvDcD-7pcKrV9W-_Z7jkYkwwrjPGPd_uckEHR_cDXyOX4PU
private rsa sign: T-I3KLkBEMRi9YdflyjNZxh_IhEC2mG4vFaq5FeFzs03l7ojtmf3pXFOwjz6qbHUwIJ-tjIMVammfCrYKa0AjMAX_L7-99_EUPmMvmjXS_8z0aZuY5dZPgRCBxklKem56r0qss-iSGTGsh3eivhUiHvtRTBXhtbkpjjlkkqXy-k
public check sign: 1
private decrypt data: i like php
public_decrypt_data
: i like java verifySign1: 1 private_decrypt_data: i like java verifySign2: 1

private_decrypt_data: i like JS

 

7.JS版本加解密

var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var b64pad = "=";

var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";

//整型转字符串
function int2char(n) {
    return BI_RM.charAt(n);
}

//十六进制转Base64字符串
function hex2b64(h) {
    var i;
    var c;
    var ret = "";
    for (i = 0; i + 3 <= h.length; i += 3) {
        c = parseInt(h.substring(i, i + 3), 16);
        ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
    }
    if (i + 1 == h.length) {
        c = parseInt(h.substring(i, i + 1), 16);
        ret += b64map.charAt(c << 2);
    }
    else if (i + 2 == h.length) {
        c = parseInt(h.substring(i, i + 2), 16);
        ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
    }
    while ((ret.length & 3) > 0) {
        ret += b64pad;
    }
    return ret;
}

//Base64字符串转十六进制
function b64tohex(s) {
    var ret = "";
    var i;
    var k = 0; // b64 state, 0-3
    var slop = 0;
    for (i = 0; i < s.length; ++i) {
        if (s.charAt(i) == b64pad) {
            break;
        }
        var v = b64map.indexOf(s.charAt(i));
        if (v < 0) {
            continue;
        }
        if (k == 0) {
            ret += int2char(v >> 2);
            slop = v & 3;
            k = 1;
        }
        else if (k == 1) {
            ret += int2char((slop << 2) | (v >> 4));
            slop = v & 0xf;
            k = 2;
        }
        else if (k == 2) {
            ret += int2char(slop);
            ret += int2char(v >> 2);
            slop = v & 3;
            k = 3;
        }
        else {
            ret += int2char((slop << 2) | (v >> 4));
            ret += int2char(v & 0xf);
            k = 0;
        }
    }
    if (k == 1) {
        ret += int2char(slop << 2);
    }
    return ret;
}

//十六进制转字节
function hexToBytes(hex) {
    for (var bytes = [], c = 0; c < hex.length; c += 2)
        bytes.push(parseInt(hex.substr(c, 2), 16));
    return bytes;
}

//字节转十六进制
function bytesToHex(bytes) {
    for (var hex = [], i = 0; i < bytes.length; i++) {
        hex.push((bytes[i] >>> 4).toString(16));
        hex.push((bytes[i] & 0xF).toString(16));
    }
    return hex.join("");
}

String.prototype.replaceAllStr=function(f,e){
    var reg=new RegExp(f,"g");
    return this.replace(reg,e);
}

function urlsafeEncode(e) {
    return e.replaceAllStr("\\+","-").replaceAllStr("/","_").replaceAllStr("=","");
}

function urlsafeDecode(e) {
    e =  e.replaceAllStr("-","+").replaceAllStr("_","/");
    var mob = e.length%4;
    if(mob>0){
        e += "====".substr(mob);
    }
    return e;
}


//长字符串加密
JSEncrypt.prototype.encryptLong = function (string) {
    var k = this.getKey();
    //var MAX_ENCRYPT_BLOCK = (((k.n.bitLength() + 7) >> 3) - 11);
    var MAX_ENCRYPT_BLOCK = 117;

    try {
        var lt = "";
        var ct = "";
        //RSA每次加密117bytes,需要辅助方法判断字符串截取位置
        //1.获取字符串截取点
        var bytes = new Array();
        bytes.push(0);
        var byteNo = 0;
        var len, c;
        len = string.length;

        var temp = 0;
        for (var i = 0; i < len; i++) {
            c = string.charCodeAt(i);
            if (c >= 0x010000 && c <= 0x10FFFF) {
                byteNo += 4;
            } else if (c >= 0x000800 && c <= 0x00FFFF) {
                byteNo += 3;
            } else if (c >= 0x000080 && c <= 0x0007FF) {
                byteNo += 2;
            } else {
                byteNo += 1;
            }
            if ((byteNo % MAX_ENCRYPT_BLOCK) >= 114 || (byteNo % MAX_ENCRYPT_BLOCK) == 0) {
                if (byteNo - temp >= 114) {
                    bytes.push(i);
                    temp = byteNo;
                }
            }
        }

        //2.截取字符串并分段加密
        if (bytes.length > 1) {
            for (var i = 0; i < bytes.length - 1; i++) {
                var str;
                if (i == 0) {
                    str = string.substring(0, bytes[i + 1] + 1);
                } else {
                    str = string.substring(bytes[i] + 1, bytes[i + 1] + 1);
                }
                var t1 = k.encrypt(str);
                ct += t1;
            }
            ;
            if (bytes[bytes.length - 1] != string.length - 1) {
                var lastStr = string.substring(bytes[bytes.length - 1] + 1);
                ct += k.encrypt(lastStr);
            }
            return hex2b64(ct);
        }
        var t = k.encrypt(string);
        var y = hex2b64(t);
        return y;
    } catch (ex) {
        return false;
    }
};

//长字符串解密
JSEncrypt.prototype.decryptLong = function (string) {
    var k = this.getKey();
    // var MAX_DECRYPT_BLOCK = ((k.n.bitLength()+7)>>3);
    var MAX_DECRYPT_BLOCK = 128;
    try {
        var ct = "";
        var t1;
        var bufTmp;
        var hexTmp;
        var str = b64tohex(string);
        var buf = hexToBytes(str);
        var inputLen = buf.length;
        //开始长度
        var offSet = 0;
        //结束长度
        var endOffSet = MAX_DECRYPT_BLOCK;

        //分段加密
        while (inputLen - offSet > 0) {
            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                bufTmp = buf.slice(offSet, endOffSet);
                hexTmp = bytesToHex(bufTmp);
                t1 = k.decrypt(hexTmp);
                ct += t1;

            } else {
                bufTmp = buf.slice(offSet, inputLen);
                hexTmp = bytesToHex(bufTmp);
                t1 = k.decrypt(hexTmp);
                ct += t1;

            }
            offSet += MAX_DECRYPT_BLOCK;
            endOffSet += MAX_DECRYPT_BLOCK;
        }
        return ct;
    } catch (ex) {
        return false;
    }
};


// Call this code when the page is done loading.
var publicKeyStr =  "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE" +
    "SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw" +
    "ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G" +
    "qvOw3G9leClSvjVnSwIDAQAB";

var privateKeyStr = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALoFIOVtGmWEww1k" +
    "EodfjF7wDARKnMdV8Bwcexf0UVIy4X3VbdzGBP+Dmf6qUssXMITeFYb/Jfk0wDFH" +
    "iZLcyWHJcrCSje0r1Rrr3Vp+h3WXE5FHchpnydXu/kG/zLgkN7gTf9/9tAgbOuha" +
    "InSxdNw7jUaq87Dcb2V4KVK+NWdLAgMBAAECgYBqCihhgJtOiarjBEvnrZkIOZCw" +
    "FZRfsWaJr9afph+BWw3dvH+/HYaV3YA4gwFlUlfPNgZRiTstX1u7+8q51HBa+08h" +
    "jPE8Q4GhoUY+sQ9MB8NXA6SWHNPPfMOYIeKEtKmNBdgIbtuhnob3o18rJNFIY+qC" +
    "i8djf4om93+AChmo6QJBAO31hd9qem7BnHXsxiMwS+iHlRjW9KxXva2zf+BNURSR" +
    "Z19cePReHJGE4v1C731MZlygTB5zKChQ8uZ3JLKJeX8CQQDIH4k/xbuhMb8dMdzl" +
    "AYN/CU+MgfWjlgbYjxOnTaLcbs5Mlz9v3/5I/FwqxPvzGuCjHkyh08oFfnQXvzdj" +
    "YMA1AkEApjgyOnzzZviBZXJueVgcPiKvSHmm0dg8W+Cd+72mXHqxPdCngPNYe2Ha" +
    "+VRPXDQI8LzcTwzbyUW6Vrh0/u2+2wJBAK1rZqx01VuimFLcWue4oBL+JolENXFF" +
    "GTmhAw8AIBmVjACjML3qBZmJ1vTZLtxEdlXkc9PojDCmnEPX2E+uD+ECQF2eX4EY" +
    "X95HDzQ4cm1kGQudjgfH1gZ+30DIindIHXNAOFpYeAUD7yUQP5tZO8nG38gybPJg" +
    "FoadlsSMIQIpksM=";


var sourceStr = "i like JS";

//公钥加密
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKeyStr);
var encrypted = encrypt.encryptLong(sourceStr);
encrypted = urlsafeEncode(encrypted);

//私钥解密
var decrypt = new JSEncrypt();
decrypt.setPrivateKey(privateKeyStr);
var uncrypted = decrypt.decryptLong(urlsafeDecode(encrypted));

console.log("public encrypted: ",encrypted);
console.log("private uncrypted: ",uncrypted);

  console.log("private uncrypted: ",decrypt.decryptLong(urlsafeDecode("WopnO2LnolZ7XpOwA_ktOhfkkaQQJQgkJudk3ZH_-ob36GQFv968nE1UBXxNekA9pIHBcvcl0ZWfwFhk-kyOF2FmQvpPY9LkqiCV0T32vhJet0n93ti2PBoFILxvChjzdOgSG9M0flH78Vm696Q4mHo7VMt_XMoHDTd3Rbagvt8")));
  console.log("private uncrypted: ",decrypt.decryptLong(urlsafeDecode("raoQQsfN0KBfPAMRWnxr9kFPvJ6BgQ7PRBCMnz0nWsH03sD4IdlMvKpj78BHe7V7Ga1HZHyDxuJhVaJ0T5qKl8qHXzvKquzNtdMru7G4X9o8ylzkGxJLg-HYCWOrsZ77ZMaKoV9p-TCf-yMI21OpL_5JGot-XNfVVPkmg0z9FW0")));

jsencrypt.js:

   1 (function (global, factory) {
   2     typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
   3         typeof define === 'function' && define.amd ? define(['exports'], factory) :
   4             (factory((global.JSEncrypt = {})));
   5 }(this, (function (exports) { 'use strict';
   6 
   7     var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
   8     function int2char(n) {
   9         return BI_RM.charAt(n);
  10     }
  11 //#region BIT_OPERATIONS
  12 // (public) this & a
  13     function op_and(x, y) {
  14         return x & y;
  15     }
  16 // (public) this | a
  17     function op_or(x, y) {
  18         return x | y;
  19     }
  20 // (public) this ^ a
  21     function op_xor(x, y) {
  22         return x ^ y;
  23     }
  24 // (public) this & ~a
  25     function op_andnot(x, y) {
  26         return x & ~y;
  27     }
  28 // return index of lowest 1-bit in x, x < 2^31
  29     function lbit(x) {
  30         if (x == 0) {
  31             return -1;
  32         }
  33         var r = 0;
  34         if ((x & 0xffff) == 0) {
  35             x >>= 16;
  36             r += 16;
  37         }
  38         if ((x & 0xff) == 0) {
  39             x >>= 8;
  40             r += 8;
  41         }
  42         if ((x & 0xf) == 0) {
  43             x >>= 4;
  44             r += 4;
  45         }
  46         if ((x & 3) == 0) {
  47             x >>= 2;
  48             r += 2;
  49         }
  50         if ((x & 1) == 0) {
  51             ++r;
  52         }
  53         return r;
  54     }
  55 // return number of 1 bits in x
  56     function cbit(x) {
  57         var r = 0;
  58         while (x != 0) {
  59             x &= x - 1;
  60             ++r;
  61         }
  62         return r;
  63     }
  64 //#endregion BIT_OPERATIONS
  65 
  66     var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  67     var b64pad = "=";
  68     function hex2b64(h) {
  69         var i;
  70         var c;
  71         var ret = "";
  72         for (i = 0; i + 3 <= h.length; i += 3) {
  73             c = parseInt(h.substring(i, i + 3), 16);
  74             ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
  75         }
  76         if (i + 1 == h.length) {
  77             c = parseInt(h.substring(i, i + 1), 16);
  78             ret += b64map.charAt(c << 2);
  79         }
  80         else if (i + 2 == h.length) {
  81             c = parseInt(h.substring(i, i + 2), 16);
  82             ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
  83         }
  84         while ((ret.length & 3) > 0) {
  85             ret += b64pad;
  86         }
  87         return ret;
  88     }
  89 // convert a base64 string to hex
  90     function b64tohex(s) {
  91         var ret = "";
  92         var i;
  93         var k = 0; // b64 state, 0-3
  94         var slop = 0;
  95         for (i = 0; i < s.length; ++i) {
  96             if (s.charAt(i) == b64pad) {
  97                 break;
  98             }
  99             var v = b64map.indexOf(s.charAt(i));
 100             if (v < 0) {
 101                 continue;
 102             }
 103             if (k == 0) {
 104                 ret += int2char(v >> 2);
 105                 slop = v & 3;
 106                 k = 1;
 107             }
 108             else if (k == 1) {
 109                 ret += int2char((slop << 2) | (v >> 4));
 110                 slop = v & 0xf;
 111                 k = 2;
 112             }
 113             else if (k == 2) {
 114                 ret += int2char(slop);
 115                 ret += int2char(v >> 2);
 116                 slop = v & 3;
 117                 k = 3;
 118             }
 119             else {
 120                 ret += int2char((slop << 2) | (v >> 4));
 121                 ret += int2char(v & 0xf);
 122                 k = 0;
 123             }
 124         }
 125         if (k == 1) {
 126             ret += int2char(slop << 2);
 127         }
 128         return ret;
 129     }
 130 
 131     /*! *****************************************************************************
 132 Copyright (c) Microsoft Corporation. All rights reserved.
 133 Licensed under the Apache License, Version 2.0 (the "License"); you may not use
 134 this file except in compliance with the License. You may obtain a copy of the
 135 License at http://www.apache.org/licenses/LICENSE-2.0
 136 
 137 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 138 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
 139 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
 140 MERCHANTABLITY OR NON-INFRINGEMENT.
 141 
 142 See the Apache Version 2.0 License for specific language governing permissions
 143 and limitations under the License.
 144 ***************************************************************************** */
 145     /* global Reflect, Promise */
 146 
 147     var extendStatics = function(d, b) {
 148         extendStatics = Object.setPrototypeOf ||
 149             ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
 150             function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
 151         return extendStatics(d, b);
 152     };
 153 
 154     function __extends(d, b) {
 155         extendStatics(d, b);
 156         function __() { this.constructor = d; }
 157         d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
 158     }
 159 
 160 // Hex JavaScript decoder
 161 // Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
 162 // Permission to use, copy, modify, and/or distribute this software for any
 163 // purpose with or without fee is hereby granted, provided that the above
 164 // copyright notice and this permission notice appear in all copies.
 165 //
 166 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 167 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 168 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 169 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 170 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 171 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 172 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 173     /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
 174     var decoder;
 175     var Hex = {
 176         decode: function (a) {
 177             var i;
 178             if (decoder === undefined) {
 179                 var hex = "0123456789ABCDEF";
 180                 var ignore = " \f\n\r\t\u00A0\u2028\u2029";
 181                 decoder = {};
 182                 for (i = 0; i < 16; ++i) {
 183                     decoder[hex.charAt(i)] = i;
 184                 }
 185                 hex = hex.toLowerCase();
 186                 for (i = 10; i < 16; ++i) {
 187                     decoder[hex.charAt(i)] = i;
 188                 }
 189                 for (i = 0; i < ignore.length; ++i) {
 190                     decoder[ignore.charAt(i)] = -1;
 191                 }
 192             }
 193             var out = [];
 194             var bits = 0;
 195             var char_count = 0;
 196             for (i = 0; i < a.length; ++i) {
 197                 var c = a.charAt(i);
 198                 if (c == "=") {
 199                     break;
 200                 }
 201                 c = decoder[c];
 202                 if (c == -1) {
 203                     continue;
 204                 }
 205                 if (c === undefined) {
 206                     throw new Error("Illegal character at offset " + i);
 207                 }
 208                 bits |= c;
 209                 if (++char_count >= 2) {
 210                     out[out.length] = bits;
 211                     bits = 0;
 212                     char_count = 0;
 213                 }
 214                 else {
 215                     bits <<= 4;
 216                 }
 217             }
 218             if (char_count) {
 219                 throw new Error("Hex encoding incomplete: 4 bits missing");
 220             }
 221             return out;
 222         }
 223     };
 224 
 225 // Base64 JavaScript decoder
 226 // Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
 227 // Permission to use, copy, modify, and/or distribute this software for any
 228 // purpose with or without fee is hereby granted, provided that the above
 229 // copyright notice and this permission notice appear in all copies.
 230 //
 231 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 232 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 233 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 234 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 235 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 236 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 237 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 238     /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
 239     var decoder$1;
 240     var Base64 = {
 241         decode: function (a) {
 242             var i;
 243             if (decoder$1 === undefined) {
 244                 var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 245                 var ignore = "= \f\n\r\t\u00A0\u2028\u2029";
 246                 decoder$1 = Object.create(null);
 247                 for (i = 0; i < 64; ++i) {
 248                     decoder$1[b64.charAt(i)] = i;
 249                 }
 250                 for (i = 0; i < ignore.length; ++i) {
 251                     decoder$1[ignore.charAt(i)] = -1;
 252                 }
 253             }
 254             var out = [];
 255             var bits = 0;
 256             var char_count = 0;
 257             for (i = 0; i < a.length; ++i) {
 258                 var c = a.charAt(i);
 259                 if (c == "=") {
 260                     break;
 261                 }
 262                 c = decoder$1[c];
 263                 if (c == -1) {
 264                     continue;
 265                 }
 266                 if (c === undefined) {
 267                     throw new Error("Illegal character at offset " + i);
 268                 }
 269                 bits |= c;
 270                 if (++char_count >= 4) {
 271                     out[out.length] = (bits >> 16);
 272                     out[out.length] = (bits >> 8) & 0xFF;
 273                     out[out.length] = bits & 0xFF;
 274                     bits = 0;
 275                     char_count = 0;
 276                 }
 277                 else {
 278                     bits <<= 6;
 279                 }
 280             }
 281             switch (char_count) {
 282                 case 1:
 283                     throw new Error("Base64 encoding incomplete: at least 2 bits missing");
 284                 case 2:
 285                     out[out.length] = (bits >> 10);
 286                     break;
 287                 case 3:
 288                     out[out.length] = (bits >> 16);
 289                     out[out.length] = (bits >> 8) & 0xFF;
 290                     break;
 291             }
 292             return out;
 293         },
 294         re: /-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/,
 295         unarmor: function (a) {
 296             var m = Base64.re.exec(a);
 297             if (m) {
 298                 if (m[1]) {
 299                     a = m[1];
 300                 }
 301                 else if (m[2]) {
 302                     a = m[2];
 303                 }
 304                 else {
 305                     throw new Error("RegExp out of sync");
 306                 }
 307             }
 308             return Base64.decode(a);
 309         }
 310     };
 311 
 312 // Big integer base-10 printing library
 313 // Copyright (c) 2014 Lapo Luchini <lapo@lapo.it>
 314 // Permission to use, copy, modify, and/or distribute this software for any
 315 // purpose with or without fee is hereby granted, provided that the above
 316 // copyright notice and this permission notice appear in all copies.
 317 //
 318 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 319 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 320 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 321 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 322 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 323 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 324 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 325     /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
 326     var max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256
 327     var Int10 = /** @class */ (function () {
 328         function Int10(value) {
 329             this.buf = [+value || 0];
 330         }
 331         Int10.prototype.mulAdd = function (m, c) {
 332             // assert(m <= 256)
 333             var b = this.buf;
 334             var l = b.length;
 335             var i;
 336             var t;
 337             for (i = 0; i < l; ++i) {
 338                 t = b[i] * m + c;
 339                 if (t < max) {
 340                     c = 0;
 341                 }
 342                 else {
 343                     c = 0 | (t / max);
 344                     t -= c * max;
 345                 }
 346                 b[i] = t;
 347             }
 348             if (c > 0) {
 349                 b[i] = c;
 350             }
 351         };
 352         Int10.prototype.sub = function (c) {
 353             // assert(m <= 256)
 354             var b = this.buf;
 355             var l = b.length;
 356             var i;
 357             var t;
 358             for (i = 0; i < l; ++i) {
 359                 t = b[i] - c;
 360                 if (t < 0) {
 361                     t += max;
 362                     c = 1;
 363                 }
 364                 else {
 365                     c = 0;
 366                 }
 367                 b[i] = t;
 368             }
 369             while (b[b.length - 1] === 0) {
 370                 b.pop();
 371             }
 372         };
 373         Int10.prototype.toString = function (base) {
 374             if ((base || 10) != 10) {
 375                 throw new Error("only base 10 is supported");
 376             }
 377             var b = this.buf;
 378             var s = b[b.length - 1].toString();
 379             for (var i = b.length - 2; i >= 0; --i) {
 380                 s += (max + b[i]).toString().substring(1);
 381             }
 382             return s;
 383         };
 384         Int10.prototype.valueOf = function () {
 385             var b = this.buf;
 386             var v = 0;
 387             for (var i = b.length - 1; i >= 0; --i) {
 388                 v = v * max + b[i];
 389             }
 390             return v;
 391         };
 392         Int10.prototype.simplify = function () {
 393             var b = this.buf;
 394             return (b.length == 1) ? b[0] : this;
 395         };
 396         return Int10;
 397     }());
 398 
 399 // ASN.1 JavaScript decoder
 400     var ellipsis = "\u2026";
 401     var reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
 402     var reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
 403     function stringCut(str, len) {
 404         if (str.length > len) {
 405             str = str.substring(0, len) + ellipsis;
 406         }
 407         return str;
 408     }
 409     var Stream = /** @class */ (function () {
 410         function Stream(enc, pos) {
 411             this.hexDigits = "0123456789ABCDEF";
 412             if (enc instanceof Stream) {
 413                 this.enc = enc.enc;
 414                 this.pos = enc.pos;
 415             }
 416             else {
 417                 // enc should be an array or a binary string
 418                 this.enc = enc;
 419                 this.pos = pos;
 420             }
 421         }
 422         Stream.prototype.get = function (pos) {
 423             if (pos === undefined) {
 424                 pos = this.pos++;
 425             }
 426             if (pos >= this.enc.length) {
 427                 throw new Error("Requesting byte offset " + pos + " on a stream of length " + this.enc.length);
 428             }
 429             return ("string" === typeof this.enc) ? this.enc.charCodeAt(pos) : this.enc[pos];
 430         };
 431         Stream.prototype.hexByte = function (b) {
 432             return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);
 433         };
 434         Stream.prototype.hexDump = function (start, end, raw) {
 435             var s = "";
 436             for (var i = start; i < end; ++i) {
 437                 s += this.hexByte(this.get(i));
 438                 if (raw !== true) {
 439                     switch (i & 0xF) {
 440                         case 0x7:
 441                             s += "  ";
 442                             break;
 443                         case 0xF:
 444                             s += "\n";
 445                             break;
 446                         default:
 447                             s += " ";
 448                     }
 449                 }
 450             }
 451             return s;
 452         };
 453         Stream.prototype.isASCII = function (start, end) {
 454             for (var i = start; i < end; ++i) {
 455                 var c = this.get(i);
 456                 if (c < 32 || c > 176) {
 457                     return false;
 458                 }
 459             }
 460             return true;
 461         };
 462         Stream.prototype.parseStringISO = function (start, end) {
 463             var s = "";
 464             for (var i = start; i < end; ++i) {
 465                 s += String.fromCharCode(this.get(i));
 466             }
 467             return s;
 468         };
 469         Stream.prototype.parseStringUTF = function (start, end) {
 470             var s = "";
 471             for (var i = start; i < end;) {
 472                 var c = this.get(i++);
 473                 if (c < 128) {
 474                     s += String.fromCharCode(c);
 475                 }
 476                 else if ((c > 191) && (c < 224)) {
 477                     s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F));
 478                 }
 479                 else {
 480                     s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F));
 481                 }
 482             }
 483             return s;
 484         };
 485         Stream.prototype.parseStringBMP = function (start, end) {
 486             var str = "";
 487             var hi;
 488             var lo;
 489             for (var i = start; i < end;) {
 490                 hi = this.get(i++);
 491                 lo = this.get(i++);
 492                 str += String.fromCharCode((hi << 8) | lo);
 493             }
 494             return str;
 495         };
 496         Stream.prototype.parseTime = function (start, end, shortYear) {
 497             var s = this.parseStringISO(start, end);
 498             var m = (shortYear ? reTimeS : reTimeL).exec(s);
 499             if (!m) {
 500                 return "Unrecognized time: " + s;
 501             }
 502             if (shortYear) {
 503                 // to avoid querying the timer, use the fixed range [1970, 2069]
 504                 // it will conform with ITU X.400 [-10, +40] sliding window until 2030
 505                 m[1] = +m[1];
 506                 m[1] += (+m[1] < 70) ? 2000 : 1900;
 507             }
 508             s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4];
 509             if (m[5]) {
 510                 s += ":" + m[5];
 511                 if (m[6]) {
 512                     s += ":" + m[6];
 513                     if (m[7]) {
 514                         s += "." + m[7];
 515                     }
 516                 }
 517             }
 518             if (m[8]) {
 519                 s += " UTC";
 520                 if (m[8] != "Z") {
 521                     s += m[8];
 522                     if (m[9]) {
 523                         s += ":" + m[9];
 524                     }
 525                 }
 526             }
 527             return s;
 528         };
 529         Stream.prototype.parseInteger = function (start, end) {
 530             var v = this.get(start);
 531             var neg = (v > 127);
 532             var pad = neg ? 255 : 0;
 533             var len;
 534             var s = "";
 535             // skip unuseful bits (not allowed in DER)
 536             while (v == pad && ++start < end) {
 537                 v = this.get(start);
 538             }
 539             len = end - start;
 540             if (len === 0) {
 541                 return neg ? -1 : 0;
 542             }
 543             // show bit length of huge integers
 544             if (len > 4) {
 545                 s = v;
 546                 len <<= 3;
 547                 while (((+s ^ pad) & 0x80) == 0) {
 548                     s = +s << 1;
 549                     --len;
 550                 }
 551                 s = "(" + len + " bit)\n";
 552             }
 553             // decode the integer
 554             if (neg) {
 555                 v = v - 256;
 556             }
 557             var n = new Int10(v);
 558             for (var i = start + 1; i < end; ++i) {
 559                 n.mulAdd(256, this.get(i));
 560             }
 561             return s + n.toString();
 562         };
 563         Stream.prototype.parseBitString = function (start, end, maxLength) {
 564             var unusedBit = this.get(start);
 565             var lenBit = ((end - start - 1) << 3) - unusedBit;
 566             var intro = "(" + lenBit + " bit)\n";
 567             var s = "";
 568             for (var i = start + 1; i < end; ++i) {
 569                 var b = this.get(i);
 570                 var skip = (i == end - 1) ? unusedBit : 0;
 571                 for (var j = 7; j >= skip; --j) {
 572                     s += (b >> j) & 1 ? "1" : "0";
 573                 }
 574                 if (s.length > maxLength) {
 575                     return intro + stringCut(s, maxLength);
 576                 }
 577             }
 578             return intro + s;
 579         };
 580         Stream.prototype.parseOctetString = function (start, end, maxLength) {
 581             if (this.isASCII(start, end)) {
 582                 return stringCut(this.parseStringISO(start, end), maxLength);
 583             }
 584             var len = end - start;
 585             var s = "(" + len + " byte)\n";
 586             maxLength /= 2; // we work in bytes
 587             if (len > maxLength) {
 588                 end = start + maxLength;
 589             }
 590             for (var i = start; i < end; ++i) {
 591                 s += this.hexByte(this.get(i));
 592             }
 593             if (len > maxLength) {
 594                 s += ellipsis;
 595             }
 596             return s;
 597         };
 598         Stream.prototype.parseOID = function (start, end, maxLength) {
 599             var s = "";
 600             var n = new Int10();
 601             var bits = 0;
 602             for (var i = start; i < end; ++i) {
 603                 var v = this.get(i);
 604                 n.mulAdd(128, v & 0x7F);
 605                 bits += 7;
 606                 if (!(v & 0x80)) { // finished
 607                     if (s === "") {
 608                         n = n.simplify();
 609                         if (n instanceof Int10) {
 610                             n.sub(80);
 611                             s = "2." + n.toString();
 612                         }
 613                         else {
 614                             var m = n < 80 ? n < 40 ? 0 : 1 : 2;
 615                             s = m + "." + (n - m * 40);
 616                         }
 617                     }
 618                     else {
 619                         s += "." + n.toString();
 620                     }
 621                     if (s.length > maxLength) {
 622                         return stringCut(s, maxLength);
 623                     }
 624                     n = new Int10();
 625                     bits = 0;
 626                 }
 627             }
 628             if (bits > 0) {
 629                 s += ".incomplete";
 630             }
 631             return s;
 632         };
 633         return Stream;
 634     }());
 635     var ASN1 = /** @class */ (function () {
 636         function ASN1(stream, header, length, tag, sub) {
 637             if (!(tag instanceof ASN1Tag)) {
 638                 throw new Error("Invalid tag value.");
 639             }
 640             this.stream = stream;
 641             this.header = header;
 642             this.length = length;
 643             this.tag = tag;
 644             this.sub = sub;
 645         }
 646         ASN1.prototype.typeName = function () {
 647             switch (this.tag.tagClass) {
 648                 case 0: // universal
 649                     switch (this.tag.tagNumber) {
 650                         case 0x00:
 651                             return "EOC";
 652                         case 0x01:
 653                             return "BOOLEAN";
 654                         case 0x02:
 655                             return "INTEGER";
 656                         case 0x03:
 657                             return "BIT_STRING";
 658                         case 0x04:
 659                             return "OCTET_STRING";
 660                         case 0x05:
 661                             return "NULL";
 662                         case 0x06:
 663                             return "OBJECT_IDENTIFIER";
 664                         case 0x07:
 665                             return "ObjectDescriptor";
 666                         case 0x08:
 667                             return "EXTERNAL";
 668                         case 0x09:
 669                             return "REAL";
 670                         case 0x0A:
 671                             return "ENUMERATED";
 672                         case 0x0B:
 673                             return "EMBEDDED_PDV";
 674                         case 0x0C:
 675                             return "UTF8String";
 676                         case 0x10:
 677                             return "SEQUENCE";
 678                         case 0x11:
 679                             return "SET";
 680                         case 0x12:
 681                             return "NumericString";
 682                         case 0x13:
 683                             return "PrintableString"; // ASCII subset
 684                         case 0x14:
 685                             return "TeletexString"; // aka T61String
 686                         case 0x15:
 687                             return "VideotexString";
 688                         case 0x16:
 689                             return "IA5String"; // ASCII
 690                         case 0x17:
 691                             return "UTCTime";
 692                         case 0x18:
 693                             return "GeneralizedTime";
 694                         case 0x19:
 695                             return "GraphicString";
 696                         case 0x1A:
 697                             return "VisibleString"; // ASCII subset
 698                         case 0x1B:
 699                             return "GeneralString";
 700                         case 0x1C:
 701                             return "UniversalString";
 702                         case 0x1E:
 703                             return "BMPString";
 704                     }
 705                     return "Universal_" + this.tag.tagNumber.toString();
 706                 case 1:
 707                     return "Application_" + this.tag.tagNumber.toString();
 708                 case 2:
 709                     return "[" + this.tag.tagNumber.toString() + "]"; // Context
 710                 case 3:
 711                     return "Private_" + this.tag.tagNumber.toString();
 712             }
 713         };
 714         ASN1.prototype.content = function (maxLength) {
 715             if (this.tag === undefined) {
 716                 return null;
 717             }
 718             if (maxLength === undefined) {
 719                 maxLength = Infinity;
 720             }
 721             var content = this.posContent();
 722             var len = Math.abs(this.length);
 723             if (!this.tag.isUniversal()) {
 724                 if (this.sub !== null) {
 725                     return "(" + this.sub.length + " elem)";
 726                 }
 727                 return this.stream.parseOctetString(content, content + len, maxLength);
 728             }
 729             switch (this.tag.tagNumber) {
 730                 case 0x01: // BOOLEAN
 731                     return (this.stream.get(content) === 0) ? "false" : "true";
 732                 case 0x02: // INTEGER
 733                     return this.stream.parseInteger(content, content + len);
 734                 case 0x03: // BIT_STRING
 735                     return this.sub ? "(" + this.sub.length + " elem)" :
 736                         this.stream.parseBitString(content, content + len, maxLength);
 737                 case 0x04: // OCTET_STRING
 738                     return this.sub ? "(" + this.sub.length + " elem)" :
 739                         this.stream.parseOctetString(content, content + len, maxLength);
 740                 // case 0x05: // NULL
 741                 case 0x06: // OBJECT_IDENTIFIER
 742                     return this.stream.parseOID(content, content + len, maxLength);
 743                 // case 0x07: // ObjectDescriptor
 744                 // case 0x08: // EXTERNAL
 745                 // case 0x09: // REAL
 746                 // case 0x0A: // ENUMERATED
 747                 // case 0x0B: // EMBEDDED_PDV
 748                 case 0x10: // SEQUENCE
 749                 case 0x11: // SET
 750                     if (this.sub !== null) {
 751                         return "(" + this.sub.length + " elem)";
 752                     }
 753                     else {
 754                         return "(no elem)";
 755                     }
 756                 case 0x0C: // UTF8String
 757                     return stringCut(this.stream.parseStringUTF(content, content + len), maxLength);
 758                 case 0x12: // NumericString
 759                 case 0x13: // PrintableString
 760                 case 0x14: // TeletexString
 761                 case 0x15: // VideotexString
 762                 case 0x16: // IA5String
 763                 // case 0x19: // GraphicString
 764                 case 0x1A: // VisibleString
 765                     // case 0x1B: // GeneralString
 766                     // case 0x1C: // UniversalString
 767                     return stringCut(this.stream.parseStringISO(content, content + len), maxLength);
 768                 case 0x1E: // BMPString
 769                     return stringCut(this.stream.parseStringBMP(content, content + len), maxLength);
 770                 case 0x17: // UTCTime
 771                 case 0x18: // GeneralizedTime
 772                     return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17));
 773             }
 774             return null;
 775         };
 776         ASN1.prototype.toString = function () {
 777             return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? "null" : this.sub.length) + "]";
 778         };
 779         ASN1.prototype.toPrettyString = function (indent) {
 780             if (indent === undefined) {
 781                 indent = "";
 782             }
 783             var s = indent + this.typeName() + " @" + this.stream.pos;
 784             if (this.length >= 0) {
 785                 s += "+";
 786             }
 787             s += this.length;
 788             if (this.tag.tagConstructed) {
 789                 s += " (constructed)";
 790             }
 791             else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null)) {
 792                 s += " (encapsulates)";
 793             }
 794             s += "\n";
 795             if (this.sub !== null) {
 796                 indent += "  ";
 797                 for (var i = 0, max = this.sub.length; i < max; ++i) {
 798                     s += this.sub[i].toPrettyString(indent);
 799                 }
 800             }
 801             return s;
 802         };
 803         ASN1.prototype.posStart = function () {
 804             return this.stream.pos;
 805         };
 806         ASN1.prototype.posContent = function () {
 807             return this.stream.pos + this.header;
 808         };
 809         ASN1.prototype.posEnd = function () {
 810             return this.stream.pos + this.header + Math.abs(this.length);
 811         };
 812         ASN1.prototype.toHexString = function () {
 813             return this.stream.hexDump(this.posStart(), this.posEnd(), true);
 814         };
 815         ASN1.decodeLength = function (stream) {
 816             var buf = stream.get();
 817             var len = buf & 0x7F;
 818             if (len == buf) {
 819                 return len;
 820             }
 821             // no reason to use Int10, as it would be a huge buffer anyways
 822             if (len > 6) {
 823                 throw new Error("Length over 48 bits not supported at position " + (stream.pos - 1));
 824             }
 825             if (len === 0) {
 826                 return null;
 827             } // undefined
 828             buf = 0;
 829             for (var i = 0; i < len; ++i) {
 830                 buf = (buf * 256) + stream.get();
 831             }
 832             return buf;
 833         };
 834         /**
 835          * Retrieve the hexadecimal value (as a string) of the current ASN.1 element
 836          * @returns {string}
 837          * @public
 838          */
 839         ASN1.prototype.getHexStringValue = function () {
 840             var hexString = this.toHexString();
 841             var offset = this.header * 2;
 842             var length = this.length * 2;
 843             return hexString.substr(offset, length);
 844         };
 845         ASN1.decode = function (str) {
 846             var stream;
 847             if (!(str instanceof Stream)) {
 848                 stream = new Stream(str, 0);
 849             }
 850             else {
 851                 stream = str;
 852             }
 853             var streamStart = new Stream(stream);
 854             var tag = new ASN1Tag(stream);
 855             var len = ASN1.decodeLength(stream);
 856             var start = stream.pos;
 857             var header = start - streamStart.pos;
 858             var sub = null;
 859             var getSub = function () {
 860                 var ret = [];
 861                 if (len !== null) {
 862                     // definite length
 863                     var end = start + len;
 864                     while (stream.pos < end) {
 865                         ret[ret.length] = ASN1.decode(stream);
 866                     }
 867                     if (stream.pos != end) {
 868                         throw new Error("Content size is not correct for container starting at offset " + start);
 869                     }
 870                 }
 871                 else {
 872                     // undefined length
 873                     try {
 874                         for (;;) {
 875                             var s = ASN1.decode(stream);
 876                             if (s.tag.isEOC()) {
 877                                 break;
 878                             }
 879                             ret[ret.length] = s;
 880                         }
 881                         len = start - stream.pos; // undefined lengths are represented as negative values
 882                     }
 883                     catch (e) {
 884                         throw new Error("Exception while decoding undefined length content: " + e);
 885                     }
 886                 }
 887                 return ret;
 888             };
 889             if (tag.tagConstructed) {
 890                 // must have valid content
 891                 sub = getSub();
 892             }
 893             else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) {
 894                 // sometimes BitString and OctetString are used to encapsulate ASN.1
 895                 try {
 896                     if (tag.tagNumber == 0x03) {
 897                         if (stream.get() != 0) {
 898                             throw new Error("BIT STRINGs with unused bits cannot encapsulate.");
 899                         }
 900                     }
 901                     sub = getSub();
 902                     for (var i = 0; i < sub.length; ++i) {
 903                         if (sub[i].tag.isEOC()) {
 904                             throw new Error("EOC is not supposed to be actual content.");
 905                         }
 906                     }
 907                 }
 908                 catch (e) {
 909                     // but silently ignore when they don't
 910                     sub = null;
 911                 }
 912             }
 913             if (sub === null) {
 914                 if (len === null) {
 915                     throw new Error("We can't skip over an invalid tag with undefined length at offset " + start);
 916                 }
 917                 stream.pos = start + Math.abs(len);
 918             }
 919             return new ASN1(streamStart, header, len, tag, sub);
 920         };
 921         return ASN1;
 922     }());
 923     var ASN1Tag = /** @class */ (function () {
 924         function ASN1Tag(stream) {
 925             var buf = stream.get();
 926             this.tagClass = buf >> 6;
 927             this.tagConstructed = ((buf & 0x20) !== 0);
 928             this.tagNumber = buf & 0x1F;
 929             if (this.tagNumber == 0x1F) { // long tag
 930                 var n = new Int10();
 931                 do {
 932                     buf = stream.get();
 933                     n.mulAdd(128, buf & 0x7F);
 934                 } while (buf & 0x80);
 935                 this.tagNumber = n.simplify();
 936             }
 937         }
 938         ASN1Tag.prototype.isUniversal = function () {
 939             return this.tagClass === 0x00;
 940         };
 941         ASN1Tag.prototype.isEOC = function () {
 942             return this.tagClass === 0x00 && this.tagNumber === 0x00;
 943         };
 944         return ASN1Tag;
 945     }());
 946 
 947 // Copyright (c) 2005  Tom Wu
 948 // Bits per digit
 949     var dbits;
 950 // JavaScript engine analysis
 951     var canary = 0xdeadbeefcafe;
 952     var j_lm = ((canary & 0xffffff) == 0xefcafe);
 953 //#region
 954     var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
 955     var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
 956 //#endregion
 957 // (public) Constructor
 958     var BigInteger = /** @class */ (function () {
 959         function BigInteger(a, b, c) {
 960             if (a != null) {
 961                 if ("number" == typeof a) {
 962                     this.fromNumber(a, b, c);
 963                 }
 964                 else if (b == null && "string" != typeof a) {
 965                     this.fromString(a, 256);
 966                 }
 967                 else {
 968                     this.fromString(a, b);
 969                 }
 970             }
 971         }
 972         //#region PUBLIC
 973         // BigInteger.prototype.toString = bnToString;
 974         // (public) return string representation in given radix
 975         BigInteger.prototype.toString = function (b) {
 976             if (this.s < 0) {
 977                 return "-" + this.negate().toString(b);
 978             }
 979             var k;
 980             if (b == 16) {
 981                 k = 4;
 982             }
 983             else if (b == 8) {
 984                 k = 3;
 985             }
 986             else if (b == 2) {
 987                 k = 1;
 988             }
 989             else if (b == 32) {
 990                 k = 5;
 991             }
 992             else if (b == 4) {
 993                 k = 2;
 994             }
 995             else {
 996                 return this.toRadix(b);
 997             }
 998             var km = (1 << k) - 1;
 999             var d;
1000             var m = false;
1001             var r = "";
1002             var i = this.t;
1003             var p = this.DB - (i * this.DB) % k;
1004             if (i-- > 0) {
1005                 if (p < this.DB && (d = this[i] >> p) > 0) {
1006                     m = true;
1007                     r = int2char(d);
1008                 }
1009                 while (i >= 0) {
1010                     if (p < k) {
1011                         d = (this[i] & ((1 << p) - 1)) << (k - p);
1012                         d |= this[--i] >> (p += this.DB - k);
1013                     }
1014                     else {
1015                         d = (this[i] >> (p -= k)) & km;
1016                         if (p <= 0) {
1017                             p += this.DB;
1018                             --i;
1019                         }
1020                     }
1021                     if (d > 0) {
1022                         m = true;
1023                     }
1024                     if (m) {
1025                         r += int2char(d);
1026                     }
1027                 }
1028             }
1029             return m ? r : "0";
1030         };
1031         // BigInteger.prototype.negate = bnNegate;
1032         // (public) -this
1033         BigInteger.prototype.negate = function () {
1034             var r = nbi();
1035             BigInteger.ZERO.subTo(this, r);
1036             return r;
1037         };
1038         // BigInteger.prototype.abs = bnAbs;
1039         // (public) |this|
1040         BigInteger.prototype.abs = function () {
1041             return (this.s < 0) ? this.negate() : this;
1042         };
1043         // BigInteger.prototype.compareTo = bnCompareTo;
1044         // (public) return + if this > a, - if this < a, 0 if equal
1045         BigInteger.prototype.compareTo = function (a) {
1046             var r = this.s - a.s;
1047             if (r != 0) {
1048                 return r;
1049             }
1050             var i = this.t;
1051             r = i - a.t;
1052             if (r != 0) {
1053                 return (this.s < 0) ? -r : r;
1054             }
1055             while (--i >= 0) {
1056                 if ((r = this[i] - a[i]) != 0) {
1057                     return r;
1058                 }
1059             }
1060             return 0;
1061         };
1062         // BigInteger.prototype.bitLength = bnBitLength;
1063         // (public) return the number of bits in "this"
1064         BigInteger.prototype.bitLength = function () {
1065             if (this.t <= 0) {
1066                 return 0;
1067             }
1068             return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
1069         };
1070         // BigInteger.prototype.mod = bnMod;
1071         // (public) this mod a
1072         BigInteger.prototype.mod = function (a) {
1073             var r = nbi();
1074             this.abs().divRemTo(a, null, r);
1075             if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) {
1076                 a.subTo(r, r);
1077             }
1078             return r;
1079         };
1080         // BigInteger.prototype.modPowInt = bnModPowInt;
1081         // (public) this^e % m, 0 <= e < 2^32
1082         BigInteger.prototype.modPowInt = function (e, m) {
1083             var z;
1084             if (e < 256 || m.isEven()) {
1085                 z = new Classic(m);
1086             }
1087             else {
1088                 z = new Montgomery(m);
1089             }
1090             return this.exp(e, z);
1091         };
1092         // BigInteger.prototype.clone = bnClone;
1093         // (public)
1094         BigInteger.prototype.clone = function () {
1095             var r = nbi();
1096             this.copyTo(r);
1097             return r;
1098         };
1099         // BigInteger.prototype.intValue = bnIntValue;
1100         // (public) return value as integer
1101         BigInteger.prototype.intValue = function () {
1102             if (this.s < 0) {
1103                 if (this.t == 1) {
1104                     return this[0] - this.DV;
1105                 }
1106                 else if (this.t == 0) {
1107                     return -1;
1108                 }
1109             }
1110             else if (this.t == 1) {
1111                 return this[0];
1112             }
1113             else if (this.t == 0) {
1114                 return 0;
1115             }
1116             // assumes 16 < DB < 32
1117             return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
1118         };
1119         // BigInteger.prototype.byteValue = bnByteValue;
1120         // (public) return value as byte
1121         BigInteger.prototype.byteValue = function () {
1122             return (this.t == 0) ? this.s : (this[0] << 24) >> 24;
1123         };
1124         // BigInteger.prototype.shortValue = bnShortValue;
1125         // (public) return value as short (assumes DB>=16)
1126         BigInteger.prototype.shortValue = function () {
1127             return (this.t == 0) ? this.s : (this[0] << 16) >> 16;
1128         };
1129         // BigInteger.prototype.signum = bnSigNum;
1130         // (public) 0 if this == 0, 1 if this > 0
1131         BigInteger.prototype.signum = function () {
1132             if (this.s < 0) {
1133                 return -1;
1134             }
1135             else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) {
1136                 return 0;
1137             }
1138             else {
1139                 return 1;
1140             }
1141         };
1142         // BigInteger.prototype.toByteArray = bnToByteArray;
1143         // (public) convert to bigendian byte array
1144         BigInteger.prototype.toByteArray = function () {
1145             var i = this.t;
1146             var r = [];
1147             r[0] = this.s;
1148             var p = this.DB - (i * this.DB) % 8;
1149             var d;
1150             var k = 0;
1151             if (i-- > 0) {
1152                 if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) {
1153                     r[k++] = d | (this.s << (this.DB - p));
1154                 }
1155                 while (i >= 0) {
1156                     if (p < 8) {
1157                         d = (this[i] & ((1 << p) - 1)) << (8 - p);
1158                         d |= this[--i] >> (p += this.DB - 8);
1159                     }
1160                     else {
1161                         d = (this[i] >> (p -= 8)) & 0xff;
1162                         if (p <= 0) {
1163                             p += this.DB;
1164                             --i;
1165                         }
1166                     }
1167                     if ((d & 0x80) != 0) {
1168                         d |= -256;
1169                     }
1170                     if (k == 0 && (this.s & 0x80) != (d & 0x80)) {
1171                         ++k;
1172                     }
1173                     if (k > 0 || d != this.s) {
1174                         r[k++] = d;
1175                     }
1176                 }
1177             }
1178             return r;
1179         };
1180         // BigInteger.prototype.equals = bnEquals;
1181         BigInteger.prototype.equals = function (a) {
1182             return (this.compareTo(a) == 0);
1183         };
1184         // BigInteger.prototype.min = bnMin;
1185         BigInteger.prototype.min = function (a) {
1186             return (this.compareTo(a) < 0) ? this : a;
1187         };
1188         // BigInteger.prototype.max = bnMax;
1189         BigInteger.prototype.max = function (a) {
1190             return (this.compareTo(a) > 0) ? this : a;
1191         };
1192         // BigInteger.prototype.and = bnAnd;
1193         BigInteger.prototype.and = function (a) {
1194             var r = nbi();
1195             this.bitwiseTo(a, op_and, r);
1196             return r;
1197         };
1198         // BigInteger.prototype.or = bnOr;
1199         BigInteger.prototype.or = function (a) {
1200             var r = nbi();
1201             this.bitwiseTo(a, op_or, r);
1202             return r;
1203         };
1204         // BigInteger.prototype.xor = bnXor;
1205         BigInteger.prototype.xor = function (a) {
1206             var r = nbi();
1207             this.bitwiseTo(a, op_xor, r);
1208             return r;
1209         };
1210         // BigInteger.prototype.andNot = bnAndNot;
1211         BigInteger.prototype.andNot = function (a) {
1212             var r = nbi();
1213             this.bitwiseTo(a, op_andnot, r);
1214             return r;
1215         };
1216         // BigInteger.prototype.not = bnNot;
1217         // (public) ~this
1218         BigInteger.prototype.not = function () {
1219             var r = nbi();
1220             for (var i = 0; i < this.t; ++i) {
1221                 r[i] = this.DM & ~this[i];
1222             }
1223             r.t = this.t;
1224             r.s = ~this.s;
1225             return r;
1226         };
1227         // BigInteger.prototype.shiftLeft = bnShiftLeft;
1228         // (public) this << n
1229         BigInteger.prototype.shiftLeft = function (n) {
1230             var r = nbi();
1231             if (n < 0) {
1232                 this.rShiftTo(-n, r);
1233             }
1234             else {
1235                 this.lShiftTo(n, r);
1236             }
1237             return r;
1238         };
1239         // BigInteger.prototype.shiftRight = bnShiftRight;
1240         // (public) this >> n
1241         BigInteger.prototype.shiftRight = function (n) {
1242             var r = nbi();
1243             if (n < 0) {
1244                 this.lShiftTo(-n, r);
1245             }
1246             else {
1247                 this.rShiftTo(n, r);
1248             }
1249             return r;
1250         };
1251         // BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
1252         // (public) returns index of lowest 1-bit (or -1 if none)
1253         BigInteger.prototype.getLowestSetBit = function () {
1254             for (var i = 0; i < this.t; ++i) {
1255                 if (this[i] != 0) {
1256                     return i * this.DB + lbit(this[i]);
1257                 }
1258             }
1259             if (this.s < 0) {
1260                 return this.t * this.DB;
1261             }
1262             return -1;
1263         };
1264         // BigInteger.prototype.bitCount = bnBitCount;
1265         // (public) return number of set bits
1266         BigInteger.prototype.bitCount = function () {
1267             var r = 0;
1268             var x = this.s & this.DM;
1269             for (var i = 0; i < this.t; ++i) {
1270                 r += cbit(this[i] ^ x);
1271             }
1272             return r;
1273         };
1274         // BigInteger.prototype.testBit = bnTestBit;
1275         // (public) true iff nth bit is set
1276         BigInteger.prototype.testBit = function (n) {
1277             var j = Math.floor(n / this.DB);
1278             if (j >= this.t) {
1279                 return (this.s != 0);
1280             }
1281             return ((this[j] & (1 << (n % this.DB))) != 0);
1282         };
1283         // BigInteger.prototype.setBit = bnSetBit;
1284         // (public) this | (1<<n)
1285         BigInteger.prototype.setBit = function (n) {
1286             return this.changeBit(n, op_or);
1287         };
1288         // BigInteger.prototype.clearBit = bnClearBit;
1289         // (public) this & ~(1<<n)
1290         BigInteger.prototype.clearBit = function (n) {
1291             return this.changeBit(n, op_andnot);
1292         };
1293         // BigInteger.prototype.flipBit = bnFlipBit;
1294         // (public) this ^ (1<<n)
1295         BigInteger.prototype.flipBit = function (n) {
1296             return this.changeBit(n, op_xor);
1297         };
1298         // BigInteger.prototype.add = bnAdd;
1299         // (public) this + a
1300         BigInteger.prototype.add = function (a) {
1301             var r = nbi();
1302             this.addTo(a, r);
1303             return r;
1304         };
1305         // BigInteger.prototype.subtract = bnSubtract;
1306         // (public) this - a
1307         BigInteger.prototype.subtract = function (a) {
1308             var r = nbi();
1309             this.subTo(a, r);
1310             return r;
1311         };
1312         // BigInteger.prototype.multiply = bnMultiply;
1313         // (public) this * a
1314         BigInteger.prototype.multiply = function (a) {
1315             var r = nbi();
1316             this.multiplyTo(a, r);
1317             return r;
1318         };
1319         // BigInteger.prototype.divide = bnDivide;
1320         // (public) this / a
1321         BigInteger.prototype.divide = function (a) {
1322             var r = nbi();
1323             this.divRemTo(a, r, null);
1324             return r;
1325         };
1326         // BigInteger.prototype.remainder = bnRemainder;
1327         // (public) this % a
1328         BigInteger.prototype.remainder = function (a) {
1329             var r = nbi();
1330             this.divRemTo(a, null, r);
1331             return r;
1332         };
1333         // BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
1334         // (public) [this/a,this%a]
1335         BigInteger.prototype.divideAndRemainder = function (a) {
1336             var q = nbi();
1337             var r = nbi();
1338             this.divRemTo(a, q, r);
1339             return [q, r];
1340         };
1341         // BigInteger.prototype.modPow = bnModPow;
1342         // (public) this^e % m (HAC 14.85)
1343         BigInteger.prototype.modPow = function (e, m) {
1344             var i = e.bitLength();
1345             var k;
1346             var r = nbv(1);
1347             var z;
1348             if (i <= 0) {
1349                 return r;
1350             }
1351             else if (i < 18) {
1352                 k = 1;
1353             }
1354             else if (i < 48) {
1355                 k = 3;
1356             }
1357             else if (i < 144) {
1358                 k = 4;
1359             }
1360             else if (i < 768) {
1361                 k = 5;
1362             }
1363             else {
1364                 k = 6;
1365             }
1366             if (i < 8) {
1367                 z = new Classic(m);
1368             }
1369             else if (m.isEven()) {
1370                 z = new Barrett(m);
1371             }
1372             else {
1373                 z = new Montgomery(m);
1374             }
1375             // precomputation
1376             var g = [];
1377             var n = 3;
1378             var k1 = k - 1;
1379             var km = (1 << k) - 1;
1380             g[1] = z.convert(this);
1381             if (k > 1) {
1382                 var g2 = nbi();
1383                 z.sqrTo(g[1], g2);
1384                 while (n <= km) {
1385                     g[n] = nbi();
1386                     z.mulTo(g2, g[n - 2], g[n]);
1387                     n += 2;
1388                 }
1389             }
1390             var j = e.t - 1;
1391             var w;
1392             var is1 = true;
1393             var r2 = nbi();
1394             var t;
1395             i = nbits(e[j]) - 1;
1396             while (j >= 0) {
1397                 if (i >= k1) {
1398                     w = (e[j] >> (i - k1)) & km;
1399                 }
1400                 else {
1401                     w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
1402                     if (j > 0) {
1403                         w |= e[j - 1] >> (this.DB + i - k1);
1404                     }
1405                 }
1406                 n = k;
1407                 while ((w & 1) == 0) {
1408                     w >>= 1;
1409                     --n;
1410                 }
1411                 if ((i -= n) < 0) {
1412                     i += this.DB;
1413                     --j;
1414                 }
1415                 if (is1) { // ret == 1, don't bother squaring or multiplying it
1416                     g[w].copyTo(r);
1417                     is1 = false;
1418                 }
1419                 else {
1420                     while (n > 1) {
1421                         z.sqrTo(r, r2);
1422                         z.sqrTo(r2, r);
1423                         n -= 2;
1424                     }
1425                     if (n > 0) {
1426                         z.sqrTo(r, r2);
1427                     }
1428                     else {
1429                         t = r;
1430                         r = r2;
1431                         r2 = t;
1432                     }
1433                     z.mulTo(r2, g[w], r);
1434                 }
1435                 while (j >= 0 && (e[j] & (1 << i)) == 0) {
1436                     z.sqrTo(r, r2);
1437                     t = r;
1438                     r = r2;
1439                     r2 = t;
1440                     if (--i < 0) {
1441                         i = this.DB - 1;
1442                         --j;
1443                     }
1444                 }
1445             }
1446             return z.revert(r);
1447         };
1448         // BigInteger.prototype.modInverse = bnModInverse;
1449         // (public) 1/this % m (HAC 14.61)
1450         BigInteger.prototype.modInverse = function (m) {
1451             var ac = m.isEven();
1452             if ((this.isEven() && ac) || m.signum() == 0) {
1453                 return BigInteger.ZERO;
1454             }
1455             var u = m.clone();
1456             var v = this.clone();
1457             var a = nbv(1);
1458             var b = nbv(0);
1459             var c = nbv(0);
1460             var d = nbv(1);
1461             while (u.signum() != 0) {
1462                 while (u.isEven()) {
1463                     u.rShiftTo(1, u);
1464                     if (ac) {
1465                         if (!a.isEven() || !b.isEven()) {
1466                             a.addTo(this, a);
1467                             b.subTo(m, b);
1468                         }
1469                         a.rShiftTo(1, a);
1470                     }
1471                     else if (!b.isEven()) {
1472                         b.subTo(m, b);
1473                     }
1474                     b.rShiftTo(1, b);
1475                 }
1476                 while (v.isEven()) {
1477                     v.rShiftTo(1, v);
1478                     if (ac) {
1479                         if (!c.isEven() || !d.isEven()) {
1480                             c.addTo(this, c);
1481                             d.subTo(m, d);
1482                         }
1483                         c.rShiftTo(1, c);
1484                     }
1485                     else if (!d.isEven()) {
1486                         d.subTo(m, d);
1487                     }
1488                     d.rShiftTo(1, d);
1489                 }
1490                 if (u.compareTo(v) >= 0) {
1491                     u.subTo(v, u);
1492                     if (ac) {
1493                         a.subTo(c, a);
1494                     }
1495                     b.subTo(d, b);
1496                 }
1497                 else {
1498                     v.subTo(u, v);
1499                     if (ac) {
1500                         c.subTo(a, c);
1501                     }
1502                     d.subTo(b, d);
1503                 }
1504             }
1505             if (v.compareTo(BigInteger.ONE) != 0) {
1506                 return BigInteger.ZERO;
1507             }
1508             if (d.compareTo(m) >= 0) {
1509                 return d.subtract(m);
1510             }
1511             if (d.signum() < 0) {
1512                 d.addTo(m, d);
1513             }
1514             else {
1515                 return d;
1516             }
1517             if (d.signum() < 0) {
1518                 return d.add(m);
1519             }
1520             else {
1521                 return d;
1522             }
1523         };
1524         // BigInteger.prototype.pow = bnPow;
1525         // (public) this^e
1526         BigInteger.prototype.pow = function (e) {
1527             return this.exp(e, new NullExp());
1528         };
1529         // BigInteger.prototype.gcd = bnGCD;
1530         // (public) gcd(this,a) (HAC 14.54)
1531         BigInteger.prototype.gcd = function (a) {
1532             var x = (this.s < 0) ? this.negate() : this.clone();
1533             var y = (a.s < 0) ? a.negate() : a.clone();
1534             if (x.compareTo(y) < 0) {
1535                 var t = x;
1536                 x = y;
1537                 y = t;
1538             }
1539             var i = x.getLowestSetBit();
1540             var g = y.getLowestSetBit();
1541             if (g < 0) {
1542                 return x;
1543             }
1544             if (i < g) {
1545                 g = i;
1546             }
1547             if (g > 0) {
1548                 x.rShiftTo(g, x);
1549                 y.rShiftTo(g, y);
1550             }
1551             while (x.signum() > 0) {
1552                 if ((i = x.getLowestSetBit()) > 0) {
1553                     x.rShiftTo(i, x);
1554                 }
1555                 if ((i = y.getLowestSetBit()) > 0) {
1556                     y.rShiftTo(i, y);
1557                 }
1558                 if (x.compareTo(y) >= 0) {
1559                     x.subTo(y, x);
1560                     x.rShiftTo(1, x);
1561                 }
1562                 else {
1563                     y.subTo(x, y);
1564                     y.rShiftTo(1, y);
1565                 }
1566             }
1567             if (g > 0) {
1568                 y.lShiftTo(g, y);
1569             }
1570             return y;
1571         };
1572         // BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
1573         // (public) test primality with certainty >= 1-.5^t
1574         BigInteger.prototype.isProbablePrime = function (t) {
1575             var i;
1576             var x = this.abs();
1577             if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
1578                 for (i = 0; i < lowprimes.length; ++i) {
1579                     if (x[0] == lowprimes[i]) {
1580                         return true;
1581                     }
1582                 }
1583                 return false;
1584             }
1585             if (x.isEven()) {
1586                 return false;
1587             }
1588             i = 1;
1589             while (i < lowprimes.length) {
1590                 var m = lowprimes[i];
1591                 var j = i + 1;
1592                 while (j < lowprimes.length && m < lplim) {
1593                     m *= lowprimes[j++];
1594                 }
1595                 m = x.modInt(m);
1596                 while (i < j) {
1597                     if (m % lowprimes[i++] == 0) {
1598                         return false;
1599                     }
1600                 }
1601             }
1602             return x.millerRabin(t);
1603         };
1604         //#endregion PUBLIC
1605         //#region PROTECTED
1606         // BigInteger.prototype.copyTo = bnpCopyTo;
1607         // (protected) copy this to r
1608         BigInteger.prototype.copyTo = function (r) {
1609             for (var i = this.t - 1; i >= 0; --i) {
1610                 r[i] = this[i];
1611             }
1612             r.t = this.t;
1613             r.s = this.s;
1614         };
1615         // BigInteger.prototype.fromInt = bnpFromInt;
1616         // (protected) set from integer value x, -DV <= x < DV
1617         BigInteger.prototype.fromInt = function (x) {
1618             this.t = 1;
1619             this.s = (x < 0) ? -1 : 0;
1620             if (x > 0) {
1621                 this[0] = x;
1622             }
1623             else if (x < -1) {
1624                 this[0] = x + this.DV;
1625             }
1626             else {
1627                 this.t = 0;
1628             }
1629         };
1630         // BigInteger.prototype.fromString = bnpFromString;
1631         // (protected) set from string and radix
1632         BigInteger.prototype.fromString = function (s, b) {
1633             var k;
1634             if (b == 16) {
1635                 k = 4;
1636             }
1637             else if (b == 8) {
1638                 k = 3;
1639             }
1640             else if (b == 256) {
1641                 k = 8;
1642                 /* byte array */
1643             }
1644             else if (b == 2) {
1645                 k = 1;
1646             }
1647             else if (b == 32) {
1648                 k = 5;
1649             }
1650             else if (b == 4) {
1651                 k = 2;
1652             }
1653             else {
1654                 this.fromRadix(s, b);
1655                 return;
1656             }
1657             this.t = 0;
1658             this.s = 0;
1659             var i = s.length;
1660             var mi = false;
1661             var sh = 0;
1662             while (--i >= 0) {
1663                 var x = (k == 8) ? (+s[i]) & 0xff : intAt(s, i);
1664                 if (x < 0) {
1665                     if (s.charAt(i) == "-") {
1666                         mi = true;
1667                     }
1668                     continue;
1669                 }
1670                 mi = false;
1671                 if (sh == 0) {
1672                     this[this.t++] = x;
1673                 }
1674                 else if (sh + k > this.DB) {
1675                     this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
1676                     this[this.t++] = (x >> (this.DB - sh));
1677                 }
1678                 else {
1679                     this[this.t - 1] |= x << sh;
1680                 }
1681                 sh += k;
1682                 if (sh >= this.DB) {
1683                     sh -= this.DB;
1684                 }
1685             }
1686             if (k == 8 && ((+s[0]) & 0x80) != 0) {
1687                 this.s = -1;
1688                 if (sh > 0) {
1689                     this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
1690                 }
1691             }
1692             this.clamp();
1693             if (mi) {
1694                 BigInteger.ZERO.subTo(this, this);
1695             }
1696         };
1697         // BigInteger.prototype.clamp = bnpClamp;
1698         // (protected) clamp off excess high words
1699         BigInteger.prototype.clamp = function () {
1700             var c = this.s & this.DM;
1701             while (this.t > 0 && this[this.t - 1] == c) {
1702                 --this.t;
1703             }
1704         };
1705         // BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
1706         // (protected) r = this << n*DB
1707         BigInteger.prototype.dlShiftTo = function (n, r) {
1708             var i;
1709             for (i = this.t - 1; i >= 0; --i) {
1710                 r[i + n] = this[i];
1711             }
1712             for (i = n - 1; i >= 0; --i) {
1713                 r[i] = 0;
1714             }
1715             r.t = this.t + n;
1716             r.s = this.s;
1717         };
1718         // BigInteger.prototype.drShiftTo = bnpDRShiftTo;
1719         // (protected) r = this >> n*DB
1720         BigInteger.prototype.drShiftTo = function (n, r) {
1721             for (var i = n; i < this.t; ++i) {
1722                 r[i - n] = this[i];
1723             }
1724             r.t = Math.max(this.t - n, 0);
1725             r.s = this.s;
1726         };
1727         // BigInteger.prototype.lShiftTo = bnpLShiftTo;
1728         // (protected) r = this << n
1729         BigInteger.prototype.lShiftTo = function (n, r) {
1730             var bs = n % this.DB;
1731             var cbs = this.DB - bs;
1732             var bm = (1 << cbs) - 1;
1733             var ds = Math.floor(n / this.DB);
1734             var c = (this.s << bs) & this.DM;
1735             for (var i = this.t - 1; i >= 0; --i) {
1736                 r[i + ds + 1] = (this[i] >> cbs) | c;
1737                 c = (this[i] & bm) << bs;
1738             }
1739             for (var i = ds - 1; i >= 0; --i) {
1740                 r[i] = 0;
1741             }
1742             r[ds] = c;
1743             r.t = this.t + ds + 1;
1744             r.s = this.s;
1745             r.clamp();
1746         };
1747         // BigInteger.prototype.rShiftTo = bnpRShiftTo;
1748         // (protected) r = this >> n
1749         BigInteger.prototype.rShiftTo = function (n, r) {
1750             r.s = this.s;
1751             var ds = Math.floor(n / this.DB);
1752             if (ds >= this.t) {
1753                 r.t = 0;
1754                 return;
1755             }
1756             var bs = n % this.DB;
1757             var cbs = this.DB - bs;
1758             var bm = (1 << bs) - 1;
1759             r[0] = this[ds] >> bs;
1760             for (var i = ds + 1; i < this.t; ++i) {
1761                 r[i - ds - 1] |= (this[i] & bm) << cbs;
1762                 r[i - ds] = this[i] >> bs;
1763             }
1764             if (bs > 0) {
1765                 r[this.t - ds - 1] |= (this.s & bm) << cbs;
1766             }
1767             r.t = this.t - ds;
1768             r.clamp();
1769         };
1770         // BigInteger.prototype.subTo = bnpSubTo;
1771         // (protected) r = this - a
1772         BigInteger.prototype.subTo = function (a, r) {
1773             var i = 0;
1774             var c = 0;
1775             var m = Math.min(a.t, this.t);
1776             while (i < m) {
1777                 c += this[i] - a[i];
1778                 r[i++] = c & this.DM;
1779                 c >>= this.DB;
1780             }
1781             if (a.t < this.t) {
1782                 c -= a.s;
1783                 while (i < this.t) {
1784                     c += this[i];
1785                     r[i++] = c & this.DM;
1786                     c >>= this.DB;
1787                 }
1788                 c += this.s;
1789             }
1790             else {
1791                 c += this.s;
1792                 while (i < a.t) {
1793                     c -= a[i];
1794                     r[i++] = c & this.DM;
1795                     c >>= this.DB;
1796                 }
1797                 c -= a.s;
1798             }
1799             r.s = (c < 0) ? -1 : 0;
1800             if (c < -1) {
1801                 r[i++] = this.DV + c;
1802             }
1803             else if (c > 0) {
1804                 r[i++] = c;
1805             }
1806             r.t = i;
1807             r.clamp();
1808         };
1809         // BigInteger.prototype.multiplyTo = bnpMultiplyTo;
1810         // (protected) r = this * a, r != this,a (HAC 14.12)
1811         // "this" should be the larger one if appropriate.
1812         BigInteger.prototype.multiplyTo = function (a, r) {
1813             var x = this.abs();
1814             var y = a.abs();
1815             var i = x.t;
1816             r.t = i + y.t;
1817             while (--i >= 0) {
1818                 r[i] = 0;
1819             }
1820             for (i = 0; i < y.t; ++i) {
1821                 r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
1822             }
1823             r.s = 0;
1824             r.clamp();
1825             if (this.s != a.s) {
1826                 BigInteger.ZERO.subTo(r, r);
1827             }
1828         };
1829         // BigInteger.prototype.squareTo = bnpSquareTo;
1830         // (protected) r = this^2, r != this (HAC 14.16)
1831         BigInteger.prototype.squareTo = function (r) {
1832             var x = this.abs();
1833             var i = r.t = 2 * x.t;
1834             while (--i >= 0) {
1835                 r[i] = 0;
1836             }
1837             for (i = 0; i < x.t - 1; ++i) {
1838                 var c = x.am(i, x[i], r, 2 * i, 0, 1);
1839                 if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
1840                     r[i + x.t] -= x.DV;
1841                     r[i + x.t + 1] = 1;
1842                 }
1843             }
1844             if (r.t > 0) {
1845                 r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
1846             }
1847             r.s = 0;
1848             r.clamp();
1849         };
1850         // BigInteger.prototype.divRemTo = bnpDivRemTo;
1851         // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
1852         // r != q, this != m.  q or r may be null.
1853         BigInteger.prototype.divRemTo = function (m, q, r) {
1854             var pm = m.abs();
1855             if (pm.t <= 0) {
1856                 return;
1857             }
1858             var pt = this.abs();
1859             if (pt.t < pm.t) {
1860                 if (q != null) {
1861                     q.fromInt(0);
1862                 }
1863                 if (r != null) {
1864                     this.copyTo(r);
1865                 }
1866                 return;
1867             }
1868             if (r == null) {
1869                 r = nbi();
1870             }
1871             var y = nbi();
1872             var ts = this.s;
1873             var ms = m.s;
1874             var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
1875             if (nsh > 0) {
1876                 pm.lShiftTo(nsh, y);
1877                 pt.lShiftTo(nsh, r);
1878             }
1879             else {
1880                 pm.copyTo(y);
1881                 pt.copyTo(r);
1882             }
1883             var ys = y.t;
1884             var y0 = y[ys - 1];
1885             if (y0 == 0) {
1886                 return;
1887             }
1888             var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
1889             var d1 = this.FV / yt;
1890             var d2 = (1 << this.F1) / yt;
1891             var e = 1 << this.F2;
1892             var i = r.t;
1893             var j = i - ys;
1894             var t = (q == null) ? nbi() : q;
1895             y.dlShiftTo(j, t);
1896             if (r.compareTo(t) >= 0) {
1897                 r[r.t++] = 1;
1898                 r.subTo(t, r);
1899             }
1900             BigInteger.ONE.dlShiftTo(ys, t);
1901             t.subTo(y, y); // "negative" y so we can replace sub with am later
1902             while (y.t < ys) {
1903                 y[y.t++] = 0;
1904             }
1905             while (--j >= 0) {
1906                 // Estimate quotient digit
1907                 var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
1908                 if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out
1909                     y.dlShiftTo(j, t);
1910                     r.subTo(t, r);
1911                     while (r[i] < --qd) {
1912                         r.subTo(t, r);
1913                     }
1914                 }
1915             }
1916             if (q != null) {
1917                 r.drShiftTo(ys, q);
1918                 if (ts != ms) {
1919                     BigInteger.ZERO.subTo(q, q);
1920                 }
1921             }
1922             r.t = ys;
1923             r.clamp();
1924             if (nsh > 0) {
1925                 r.rShiftTo(nsh, r);
1926             } // Denormalize remainder
1927             if (ts < 0) {
1928                 BigInteger.ZERO.subTo(r, r);
1929             }
1930         };
1931         // BigInteger.prototype.invDigit = bnpInvDigit;
1932         // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
1933         // justification:
1934         //         xy == 1 (mod m)
1935         //         xy =  1+km
1936         //   xy(2-xy) = (1+km)(1-km)
1937         // x[y(2-xy)] = 1-k^2m^2
1938         // x[y(2-xy)] == 1 (mod m^2)
1939         // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
1940         // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
1941         // JS multiply "overflows" differently from C/C++, so care is needed here.
1942         BigInteger.prototype.invDigit = function () {
1943             if (this.t < 1) {
1944                 return 0;
1945             }
1946             var x = this[0];
1947             if ((x & 1) == 0) {
1948                 return 0;
1949             }
1950             var y = x & 3; // y == 1/x mod 2^2
1951             y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
1952             y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
1953             y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
1954             // last step - calculate inverse mod DV directly;
1955             // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
1956             y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits
1957             // we really want the negative inverse, and -DV < y < DV
1958             return (y > 0) ? this.DV - y : -y;
1959         };
1960         // BigInteger.prototype.isEven = bnpIsEven;
1961         // (protected) true iff this is even
1962         BigInteger.prototype.isEven = function () {
1963             return ((this.t > 0) ? (this[0] & 1) : this.s) == 0;
1964         };
1965         // BigInteger.prototype.exp = bnpExp;
1966         // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
1967         BigInteger.prototype.exp = function (e, z) {
1968             if (e > 0xffffffff || e < 1) {
1969                 return BigInteger.ONE;
1970             }
1971             var r = nbi();
1972             var r2 = nbi();
1973             var g = z.convert(this);
1974             var i = nbits(e) - 1;
1975             g.copyTo(r);
1976             while (--i >= 0) {
1977                 z.sqrTo(r, r2);
1978                 if ((e & (1 << i)) > 0) {
1979                     z.mulTo(r2, g, r);
1980                 }
1981                 else {
1982                     var t = r;
1983                     r = r2;
1984                     r2 = t;
1985                 }
1986             }
1987             return z.revert(r);
1988         };
1989         // BigInteger.prototype.chunkSize = bnpChunkSize;
1990         // (protected) return x s.t. r^x < DV
1991         BigInteger.prototype.chunkSize = function (r) {
1992             return Math.floor(Math.LN2 * this.DB / Math.log(r));
1993         };
1994         // BigInteger.prototype.toRadix = bnpToRadix;
1995         // (protected) convert to radix string
1996         BigInteger.prototype.toRadix = function (b) {
1997             if (b == null) {
1998                 b = 10;
1999             }
2000             if (this.signum() == 0 || b < 2 || b > 36) {
2001                 return "0";
2002             }
2003             var cs = this.chunkSize(b);
2004             var a = Math.pow(b, cs);
2005             var d = nbv(a);
2006             var y = nbi();
2007             var z = nbi();
2008             var r = "";
2009             this.divRemTo(d, y, z);
2010             while (y.signum() > 0) {
2011                 r = (a + z.intValue()).toString(b).substr(1) + r;
2012                 y.divRemTo(d, y, z);
2013             }
2014             return z.intValue().toString(b) + r;
2015         };
2016         // BigInteger.prototype.fromRadix = bnpFromRadix;
2017         // (protected) convert from radix string
2018         BigInteger.prototype.fromRadix = function (s, b) {
2019             this.fromInt(0);
2020             if (b == null) {
2021                 b = 10;
2022             }
2023             var cs = this.chunkSize(b);
2024             var d = Math.pow(b, cs);
2025             var mi = false;
2026             var j = 0;
2027             var w = 0;
2028             for (var i = 0; i < s.length; ++i) {
2029                 var x = intAt(s, i);
2030                 if (x < 0) {
2031                     if (s.charAt(i) == "-" && this.signum() == 0) {
2032                         mi = true;
2033                     }
2034                     continue;
2035                 }
2036                 w = b * w + x;
2037                 if (++j >= cs) {
2038                     this.dMultiply(d);
2039                     this.dAddOffset(w, 0);
2040                     j = 0;
2041                     w = 0;
2042                 }
2043             }
2044             if (j > 0) {
2045                 this.dMultiply(Math.pow(b, j));
2046                 this.dAddOffset(w, 0);
2047             }
2048             if (mi) {
2049                 BigInteger.ZERO.subTo(this, this);
2050             }
2051         };
2052         // BigInteger.prototype.fromNumber = bnpFromNumber;
2053         // (protected) alternate constructor
2054         BigInteger.prototype.fromNumber = function (a, b, c) {
2055             if ("number" == typeof b) {
2056                 // new BigInteger(int,int,RNG)
2057                 if (a < 2) {
2058                     this.fromInt(1);
2059                 }
2060                 else {
2061                     this.fromNumber(a, c);
2062                     if (!this.testBit(a - 1)) {
2063                         // force MSB set
2064                         this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
2065                     }
2066                     if (this.isEven()) {
2067                         this.dAddOffset(1, 0);
2068                     } // force odd
2069                     while (!this.isProbablePrime(b)) {
2070                         this.dAddOffset(2, 0);
2071                         if (this.bitLength() > a) {
2072                             this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
2073                         }
2074                     }
2075                 }
2076             }
2077             else {
2078                 // new BigInteger(int,RNG)
2079                 var x = [];
2080                 var t = a & 7;
2081                 x.length = (a >> 3) + 1;
2082                 b.nextBytes(x);
2083                 if (t > 0) {
2084                     x[0] &= ((1 << t) - 1);
2085                 }
2086                 else {
2087                     x[0] = 0;
2088                 }
2089                 this.fromString(x, 256);
2090             }
2091         };
2092         // BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
2093         // (protected) r = this op a (bitwise)
2094         BigInteger.prototype.bitwiseTo = function (a, op, r) {
2095             var i;
2096             var f;
2097             var m = Math.min(a.t, this.t);
2098             for (i = 0; i < m; ++i) {
2099                 r[i] = op(this[i], a[i]);
2100             }
2101             if (a.t < this.t) {
2102                 f = a.s & this.DM;
2103                 for (i = m; i < this.t; ++i) {
2104                     r[i] = op(this[i], f);
2105                 }
2106                 r.t = this.t;
2107             }
2108             else {
2109                 f = this.s & this.DM;
2110                 for (i = m; i < a.t; ++i) {
2111                     r[i] = op(f, a[i]);
2112                 }
2113                 r.t = a.t;
2114             }
2115             r.s = op(this.s, a.s);
2116             r.clamp();
2117         };
2118         // BigInteger.prototype.changeBit = bnpChangeBit;
2119         // (protected) this op (1<<n)
2120         BigInteger.prototype.changeBit = function (n, op) {
2121             var r = BigInteger.ONE.shiftLeft(n);
2122             this.bitwiseTo(r, op, r);
2123             return r;
2124         };
2125         // BigInteger.prototype.addTo = bnpAddTo;
2126         // (protected) r = this + a
2127         BigInteger.prototype.addTo = function (a, r) {
2128             var i = 0;
2129             var c = 0;
2130             var m = Math.min(a.t, this.t);
2131             while (i < m) {
2132                 c += this[i] + a[i];
2133                 r[i++] = c & this.DM;
2134                 c >>= this.DB;
2135             }
2136             if (a.t < this.t) {
2137                 c += a.s;
2138                 while (i < this.t) {
2139                     c += this[i];
2140                     r[i++] = c & this.DM;
2141                     c >>= this.DB;
2142                 }
2143                 c += this.s;
2144             }
2145             else {
2146                 c += this.s;
2147                 while (i < a.t) {
2148                     c += a[i];
2149                     r[i++] = c & this.DM;
2150                     c >>= this.DB;
2151                 }
2152                 c += a.s;
2153             }
2154             r.s = (c < 0) ? -1 : 0;
2155             if (c > 0) {
2156                 r[i++] = c;
2157             }
2158             else if (c < -1) {
2159                 r[i++] = this.DV + c;
2160             }
2161             r.t = i;
2162             r.clamp();
2163         };
2164         // BigInteger.prototype.dMultiply = bnpDMultiply;
2165         // (protected) this *= n, this >= 0, 1 < n < DV
2166         BigInteger.prototype.dMultiply = function (n) {
2167             this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
2168             ++this.t;
2169             this.clamp();
2170         };
2171         // BigInteger.prototype.dAddOffset = bnpDAddOffset;
2172         // (protected) this += n << w words, this >= 0
2173         BigInteger.prototype.dAddOffset = function (n, w) {
2174             if (n == 0) {
2175                 return;
2176             }
2177             while (this.t <= w) {
2178                 this[this.t++] = 0;
2179             }
2180             this[w] += n;
2181             while (this[w] >= this.DV) {
2182                 this[w] -= this.DV;
2183                 if (++w >= this.t) {
2184                     this[this.t++] = 0;
2185                 }
2186                 ++this[w];
2187             }
2188         };
2189         // BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
2190         // (protected) r = lower n words of "this * a", a.t <= n
2191         // "this" should be the larger one if appropriate.
2192         BigInteger.prototype.multiplyLowerTo = function (a, n, r) {
2193             var i = Math.min(this.t + a.t, n);
2194             r.s = 0; // assumes a,this >= 0
2195             r.t = i;
2196             while (i > 0) {
2197                 r[--i] = 0;
2198             }
2199             for (var j = r.t - this.t; i < j; ++i) {
2200                 r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
2201             }
2202             for (var j = Math.min(a.t, n); i < j; ++i) {
2203                 this.am(0, a[i], r, i, 0, n - i);
2204             }
2205             r.clamp();
2206         };
2207         // BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
2208         // (protected) r = "this * a" without lower n words, n > 0
2209         // "this" should be the larger one if appropriate.
2210         BigInteger.prototype.multiplyUpperTo = function (a, n, r) {
2211             --n;
2212             var i = r.t = this.t + a.t - n;
2213             r.s = 0; // assumes a,this >= 0
2214             while (--i >= 0) {
2215                 r[i] = 0;
2216             }
2217             for (i = Math.max(n - this.t, 0); i < a.t; ++i) {
2218                 r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
2219             }
2220             r.clamp();
2221             r.drShiftTo(1, r);
2222         };
2223         // BigInteger.prototype.modInt = bnpModInt;
2224         // (protected) this % n, n < 2^26
2225         BigInteger.prototype.modInt = function (n) {
2226             if (n <= 0) {
2227                 return 0;
2228             }
2229             var d = this.DV % n;
2230             var r = (this.s < 0) ? n - 1 : 0;
2231             if (this.t > 0) {
2232                 if (d == 0) {
2233                     r = this[0] % n;
2234                 }
2235                 else {
2236                     for (var i = this.t - 1; i >= 0; --i) {
2237                         r = (d * r + this[i]) % n;
2238                     }
2239                 }
2240             }
2241             return r;
2242         };
2243         // BigInteger.prototype.millerRabin = bnpMillerRabin;
2244         // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
2245         BigInteger.prototype.millerRabin = function (t) {
2246             var n1 = this.subtract(BigInteger.ONE);
2247             var k = n1.getLowestSetBit();
2248             if (k <= 0) {
2249                 return false;
2250             }
2251             var r = n1.shiftRight(k);
2252             t = (t + 1) >> 1;
2253             if (t > lowprimes.length) {
2254                 t = lowprimes.length;
2255             }
2256             var a = nbi();
2257             for (var i = 0; i < t; ++i) {
2258                 // Pick bases at random, instead of starting at 2
2259                 a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
2260                 var y = a.modPow(r, this);
2261                 if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
2262                     var j = 1;
2263                     while (j++ < k && y.compareTo(n1) != 0) {
2264                         y = y.modPowInt(2, this);
2265                         if (y.compareTo(BigInteger.ONE) == 0) {
2266                             return false;
2267                         }
2268                     }
2269                     if (y.compareTo(n1) != 0) {
2270                         return false;
2271                     }
2272                 }
2273             }
2274             return true;
2275         };
2276         // BigInteger.prototype.square = bnSquare;
2277         // (public) this^2
2278         BigInteger.prototype.square = function () {
2279             var r = nbi();
2280             this.squareTo(r);
2281             return r;
2282         };
2283         //#region ASYNC
2284         // Public API method
2285         BigInteger.prototype.gcda = function (a, callback) {
2286             var x = (this.s < 0) ? this.negate() : this.clone();
2287             var y = (a.s < 0) ? a.negate() : a.clone();
2288             if (x.compareTo(y) < 0) {
2289                 var t = x;
2290                 x = y;
2291                 y = t;
2292             }
2293             var i = x.getLowestSetBit();
2294             var g = y.getLowestSetBit();
2295             if (g < 0) {
2296                 callback(x);
2297                 return;
2298             }
2299             if (i < g) {
2300                 g = i;
2301             }
2302             if (g > 0) {
2303                 x.rShiftTo(g, x);
2304                 y.rShiftTo(g, y);
2305             }
2306             // Workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen.
2307             var gcda1 = function () {
2308                 if ((i = x.getLowestSetBit()) > 0) {
2309                     x.rShiftTo(i, x);
2310                 }
2311                 if ((i = y.getLowestSetBit()) > 0) {
2312                     y.rShiftTo(i, y);
2313                 }
2314                 if (x.compareTo(y) >= 0) {
2315                     x.subTo(y, x);
2316                     x.rShiftTo(1, x);
2317                 }
2318                 else {
2319                     y.subTo(x, y);
2320                     y.rShiftTo(1, y);
2321                 }
2322                 if (!(x.signum() > 0)) {
2323                     if (g > 0) {
2324                         y.lShiftTo(g, y);
2325                     }
2326                     setTimeout(function () { callback(y); }, 0); // escape
2327                 }
2328                 else {
2329                     setTimeout(gcda1, 0);
2330                 }
2331             };
2332             setTimeout(gcda1, 10);
2333         };
2334         // (protected) alternate constructor
2335         BigInteger.prototype.fromNumberAsync = function (a, b, c, callback) {
2336             if ("number" == typeof b) {
2337                 if (a < 2) {
2338                     this.fromInt(1);
2339                 }
2340                 else {
2341                     this.fromNumber(a, c);
2342                     if (!this.testBit(a - 1)) {
2343                         this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
2344                     }
2345                     if (this.isEven()) {
2346                         this.dAddOffset(1, 0);
2347                     }
2348                     var bnp_1 = this;
2349                     var bnpfn1_1 = function () {
2350                         bnp_1.dAddOffset(2, 0);
2351                         if (bnp_1.bitLength() > a) {
2352                             bnp_1.subTo(BigInteger.ONE.shiftLeft(a - 1), bnp_1);
2353                         }
2354                         if (bnp_1.isProbablePrime(b)) {
2355                             setTimeout(function () { callback(); }, 0); // escape
2356                         }
2357                         else {
2358                             setTimeout(bnpfn1_1, 0);
2359                         }
2360                     };
2361                     setTimeout(bnpfn1_1, 0);
2362                 }
2363             }
2364             else {
2365                 var x = [];
2366                 var t = a & 7;
2367                 x.length = (a >> 3) + 1;
2368                 b.nextBytes(x);
2369                 if (t > 0) {
2370                     x[0] &= ((1 << t) - 1);
2371                 }
2372                 else {
2373                     x[0] = 0;
2374                 }
2375                 this.fromString(x, 256);
2376             }
2377         };
2378         return BigInteger;
2379     }());
2380 //#region REDUCERS
2381 //#region NullExp
2382     var NullExp = /** @class */ (function () {
2383         function NullExp() {
2384         }
2385         // NullExp.prototype.convert = nNop;
2386         NullExp.prototype.convert = function (x) {
2387             return x;
2388         };
2389         // NullExp.prototype.revert = nNop;
2390         NullExp.prototype.revert = function (x) {
2391             return x;
2392         };
2393         // NullExp.prototype.mulTo = nMulTo;
2394         NullExp.prototype.mulTo = function (x, y, r) {
2395             x.multiplyTo(y, r);
2396         };
2397         // NullExp.prototype.sqrTo = nSqrTo;
2398         NullExp.prototype.sqrTo = function (x, r) {
2399             x.squareTo(r);
2400         };
2401         return NullExp;
2402     }());
2403 // Modular reduction using "classic" algorithm
2404     var Classic = /** @class */ (function () {
2405         function Classic(m) {
2406             this.m = m;
2407         }
2408         // Classic.prototype.convert = cConvert;
2409         Classic.prototype.convert = function (x) {
2410             if (x.s < 0 || x.compareTo(this.m) >= 0) {
2411                 return x.mod(this.m);
2412             }
2413             else {
2414                 return x;
2415             }
2416         };
2417         // Classic.prototype.revert = cRevert;
2418         Classic.prototype.revert = function (x) {
2419             return x;
2420         };
2421         // Classic.prototype.reduce = cReduce;
2422         Classic.prototype.reduce = function (x) {
2423             x.divRemTo(this.m, null, x);
2424         };
2425         // Classic.prototype.mulTo = cMulTo;
2426         Classic.prototype.mulTo = function (x, y, r) {
2427             x.multiplyTo(y, r);
2428             this.reduce(r);
2429         };
2430         // Classic.prototype.sqrTo = cSqrTo;
2431         Classic.prototype.sqrTo = function (x, r) {
2432             x.squareTo(r);
2433             this.reduce(r);
2434         };
2435         return Classic;
2436     }());
2437 //#endregion
2438 //#region Montgomery
2439 // Montgomery reduction
2440     var Montgomery = /** @class */ (function () {
2441         function Montgomery(m) {
2442             this.m = m;
2443             this.mp = m.invDigit();
2444             this.mpl = this.mp & 0x7fff;
2445             this.mph = this.mp >> 15;
2446             this.um = (1 << (m.DB - 15)) - 1;
2447             this.mt2 = 2 * m.t;
2448         }
2449         // Montgomery.prototype.convert = montConvert;
2450         // xR mod m
2451         Montgomery.prototype.convert = function (x) {
2452             var r = nbi();
2453             x.abs().dlShiftTo(this.m.t, r);
2454             r.divRemTo(this.m, null, r);
2455             if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) {
2456                 this.m.subTo(r, r);
2457             }
2458             return r;
2459         };
2460         // Montgomery.prototype.revert = montRevert;
2461         // x/R mod m
2462         Montgomery.prototype.revert = function (x) {
2463             var r = nbi();
2464             x.copyTo(r);
2465             this.reduce(r);
2466             return r;
2467         };
2468         // Montgomery.prototype.reduce = montReduce;
2469         // x = x/R mod m (HAC 14.32)
2470         Montgomery.prototype.reduce = function (x) {
2471             while (x.t <= this.mt2) {
2472                 // pad x so am has enough room later
2473                 x[x.t++] = 0;
2474             }
2475             for (var i = 0; i < this.m.t; ++i) {
2476                 // faster way of calculating u0 = x[i]*mp mod DV
2477                 var j = x[i] & 0x7fff;
2478                 var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
2479                 // use am to combine the multiply-shift-add into one call
2480                 j = i + this.m.t;
2481                 x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
2482                 // propagate carry
2483                 while (x[j] >= x.DV) {
2484                     x[j] -= x.DV;
2485                     x[++j]++;
2486                 }
2487             }
2488             x.clamp();
2489             x.drShiftTo(this.m.t, x);
2490             if (x.compareTo(this.m) >= 0) {
2491                 x.subTo(this.m, x);
2492             }
2493         };
2494         // Montgomery.prototype.mulTo = montMulTo;
2495         // r = "xy/R mod m"; x,y != r
2496         Montgomery.prototype.mulTo = function (x, y, r) {
2497             x.multiplyTo(y, r);
2498             this.reduce(r);
2499         };
2500         // Montgomery.prototype.sqrTo = montSqrTo;
2501         // r = "x^2/R mod m"; x != r
2502         Montgomery.prototype.sqrTo = function (x, r) {
2503             x.squareTo(r);
2504             this.reduce(r);
2505         };
2506         return Montgomery;
2507     }());
2508 //#endregion Montgomery
2509 //#region Barrett
2510 // Barrett modular reduction
2511     var Barrett = /** @class */ (function () {
2512         function Barrett(m) {
2513             this.m = m;
2514             // setup Barrett
2515             this.r2 = nbi();
2516             this.q3 = nbi();
2517             BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
2518             this.mu = this.r2.divide(m);
2519         }
2520         // Barrett.prototype.convert = barrettConvert;
2521         Barrett.prototype.convert = function (x) {
2522             if (x.s < 0 || x.t > 2 * this.m.t) {
2523                 return x.mod(this.m);
2524             }
2525             else if (x.compareTo(this.m) < 0) {
2526                 return x;
2527             }
2528             else {
2529                 var r = nbi();
2530                 x.copyTo(r);
2531                 this.reduce(r);
2532                 return r;
2533             }
2534         };
2535         // Barrett.prototype.revert = barrettRevert;
2536         Barrett.prototype.revert = function (x) {
2537             return x;
2538         };
2539         // Barrett.prototype.reduce = barrettReduce;
2540         // x = x mod m (HAC 14.42)
2541         Barrett.prototype.reduce = function (x) {
2542             x.drShiftTo(this.m.t - 1, this.r2);
2543             if (x.t > this.m.t + 1) {
2544                 x.t = this.m.t + 1;
2545                 x.clamp();
2546             }
2547             this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
2548             this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
2549             while (x.compareTo(this.r2) < 0) {
2550                 x.dAddOffset(1, this.m.t + 1);
2551             }
2552             x.subTo(this.r2, x);
2553             while (x.compareTo(this.m) >= 0) {
2554                 x.subTo(this.m, x);
2555             }
2556         };
2557         // Barrett.prototype.mulTo = barrettMulTo;
2558         // r = x*y mod m; x,y != r
2559         Barrett.prototype.mulTo = function (x, y, r) {
2560             x.multiplyTo(y, r);
2561             this.reduce(r);
2562         };
2563         // Barrett.prototype.sqrTo = barrettSqrTo;
2564         // r = x^2 mod m; x != r
2565         Barrett.prototype.sqrTo = function (x, r) {
2566             x.squareTo(r);
2567             this.reduce(r);
2568         };
2569         return Barrett;
2570     }());
2571 //#endregion
2572 //#endregion REDUCERS
2573 // return new, unset BigInteger
2574     function nbi() { return new BigInteger(null); }
2575     function parseBigInt(str, r) {
2576         return new BigInteger(str, r);
2577     }
2578 // am: Compute w_j += (x*this_i), propagate carries,
2579 // c is initial carry, returns final carry.
2580 // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
2581 // We need to select the fastest one that works in this environment.
2582 // am1: use a single mult and divide to get the high bits,
2583 // max digit bits should be 26 because
2584 // max internal value = 2*dvalue^2-2*dvalue (< 2^53)
2585     function am1(i, x, w, j, c, n) {
2586         while (--n >= 0) {
2587             var v = x * this[i++] + w[j] + c;
2588             c = Math.floor(v / 0x4000000);
2589             w[j++] = v & 0x3ffffff;
2590         }
2591         return c;
2592     }
2593 // am2 avoids a big mult-and-extract completely.
2594 // Max digit bits should be <= 30 because we do bitwise ops
2595 // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
2596     function am2(i, x, w, j, c, n) {
2597         var xl = x & 0x7fff;
2598         var xh = x >> 15;
2599         while (--n >= 0) {
2600             var l = this[i] & 0x7fff;
2601             var h = this[i++] >> 15;
2602             var m = xh * l + h * xl;
2603             l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
2604             c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
2605             w[j++] = l & 0x3fffffff;
2606         }
2607         return c;
2608     }
2609 // Alternately, set max digit bits to 28 since some
2610 // browsers slow down when dealing with 32-bit numbers.
2611     function am3(i, x, w, j, c, n) {
2612         var xl = x & 0x3fff;
2613         var xh = x >> 14;
2614         while (--n >= 0) {
2615             var l = this[i] & 0x3fff;
2616             var h = this[i++] >> 14;
2617             var m = xh * l + h * xl;
2618             l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
2619             c = (l >> 28) + (m >> 14) + xh * h;
2620             w[j++] = l & 0xfffffff;
2621         }
2622         return c;
2623     }
2624     if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
2625         BigInteger.prototype.am = am2;
2626         dbits = 30;
2627     }
2628     else if (j_lm && (navigator.appName != "Netscape")) {
2629         BigInteger.prototype.am = am1;
2630         dbits = 26;
2631     }
2632     else { // Mozilla/Netscape seems to prefer am3
2633         BigInteger.prototype.am = am3;
2634         dbits = 28;
2635     }
2636     BigInteger.prototype.DB = dbits;
2637     BigInteger.prototype.DM = ((1 << dbits) - 1);
2638     BigInteger.prototype.DV = (1 << dbits);
2639     var BI_FP = 52;
2640     BigInteger.prototype.FV = Math.pow(2, BI_FP);
2641     BigInteger.prototype.F1 = BI_FP - dbits;
2642     BigInteger.prototype.F2 = 2 * dbits - BI_FP;
2643 // Digit conversions
2644     var BI_RC = [];
2645     var rr;
2646     var vv;
2647     rr = "0".charCodeAt(0);
2648     for (vv = 0; vv <= 9; ++vv) {
2649         BI_RC[rr++] = vv;
2650     }
2651     rr = "a".charCodeAt(0);
2652     for (vv = 10; vv < 36; ++vv) {
2653         BI_RC[rr++] = vv;
2654     }
2655     rr = "A".charCodeAt(0);
2656     for (vv = 10; vv < 36; ++vv) {
2657         BI_RC[rr++] = vv;
2658     }
2659     function intAt(s, i) {
2660         var c = BI_RC[s.charCodeAt(i)];
2661         return (c == null) ? -1 : c;
2662     }
2663 // return bigint initialized to value
2664     function nbv(i) {
2665         var r = nbi();
2666         r.fromInt(i);
2667         return r;
2668     }
2669 // returns bit length of the integer x
2670     function nbits(x) {
2671         var r = 1;
2672         var t;
2673         if ((t = x >>> 16) != 0) {
2674             x = t;
2675             r += 16;
2676         }
2677         if ((t = x >> 8) != 0) {
2678             x = t;
2679             r += 8;
2680         }
2681         if ((t = x >> 4) != 0) {
2682             x = t;
2683             r += 4;
2684         }
2685         if ((t = x >> 2) != 0) {
2686             x = t;
2687             r += 2;
2688         }
2689         if ((t = x >> 1) != 0) {
2690             x = t;
2691             r += 1;
2692         }
2693         return r;
2694     }
2695 // "constants"
2696     BigInteger.ZERO = nbv(0);
2697     BigInteger.ONE = nbv(1);
2698 
2699 // prng4.js - uses Arcfour as a PRNG
2700     var Arcfour = /** @class */ (function () {
2701         function Arcfour() {
2702             this.i = 0;
2703             this.j = 0;
2704             this.S = [];
2705         }
2706         // Arcfour.prototype.init = ARC4init;
2707         // Initialize arcfour context from key, an array of ints, each from [0..255]
2708         Arcfour.prototype.init = function (key) {
2709             var i;
2710             var j;
2711             var t;
2712             for (i = 0; i < 256; ++i) {
2713                 this.S[i] = i;
2714             }
2715             j = 0;
2716             for (i = 0; i < 256; ++i) {
2717                 j = (j + this.S[i] + key[i % key.length]) & 255;
2718                 t = this.S[i];
2719                 this.S[i] = this.S[j];
2720                 this.S[j] = t;
2721             }
2722             this.i = 0;
2723             this.j = 0;
2724         };
2725         // Arcfour.prototype.next = ARC4next;
2726         Arcfour.prototype.next = function () {
2727             var t;
2728             this.i = (this.i + 1) & 255;
2729             this.j = (this.j + this.S[this.i]) & 255;
2730             t = this.S[this.i];
2731             this.S[this.i] = this.S[this.j];
2732             this.S[this.j] = t;
2733             return this.S[(t + this.S[this.i]) & 255];
2734         };
2735         return Arcfour;
2736     }());
2737 // Plug in your RNG constructor here
2738     function prng_newstate() {
2739         return new Arcfour();
2740     }
2741 // Pool size must be a multiple of 4 and greater than 32.
2742 // An array of bytes the size of the pool will be passed to init()
2743     var rng_psize = 256;
2744 
2745 // Random number generator - requires a PRNG backend, e.g. prng4.js
2746     var rng_state;
2747     var rng_pool = null;
2748     var rng_pptr;
2749 // Initialize the pool with junk if needed.
2750     if (rng_pool == null) {
2751         rng_pool = [];
2752         rng_pptr = 0;
2753         var t = void 0;
2754         if (window.crypto && window.crypto.getRandomValues) {
2755             // Extract entropy (2048 bits) from RNG if available
2756             var z = new Uint32Array(256);
2757             window.crypto.getRandomValues(z);
2758             for (t = 0; t < z.length; ++t) {
2759                 rng_pool[rng_pptr++] = z[t] & 255;
2760             }
2761         }
2762         // Use mouse events for entropy, if we do not have enough entropy by the time
2763         // we need it, entropy will be generated by Math.random.
2764         var onMouseMoveListener_1 = function (ev) {
2765             this.count = this.count || 0;
2766             if (this.count >= 256 || rng_pptr >= rng_psize) {
2767                 if (window.removeEventListener) {
2768                     window.removeEventListener("mousemove", onMouseMoveListener_1, false);
2769                 }
2770                 else if (window.detachEvent) {
2771                     window.detachEvent("onmousemove", onMouseMoveListener_1);
2772                 }
2773                 return;
2774             }
2775             try {
2776                 var mouseCoordinates = ev.x + ev.y;
2777                 rng_pool[rng_pptr++] = mouseCoordinates & 255;
2778                 this.count += 1;
2779             }
2780             catch (e) {
2781                 // Sometimes Firefox will deny permission to access event properties for some reason. Ignore.
2782             }
2783         };
2784         if (window.addEventListener) {
2785             window.addEventListener("mousemove", onMouseMoveListener_1, false);
2786         }
2787         else if (window.attachEvent) {
2788             window.attachEvent("onmousemove", onMouseMoveListener_1);
2789         }
2790     }
2791     function rng_get_byte() {
2792         if (rng_state == null) {
2793             rng_state = prng_newstate();
2794             // At this point, we may not have collected enough entropy.  If not, fall back to Math.random
2795             while (rng_pptr < rng_psize) {
2796                 var random = Math.floor(65536 * Math.random());
2797                 rng_pool[rng_pptr++] = random & 255;
2798             }
2799             rng_state.init(rng_pool);
2800             for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {
2801                 rng_pool[rng_pptr] = 0;
2802             }
2803             rng_pptr = 0;
2804         }
2805         // TODO: allow reseeding after first request
2806         return rng_state.next();
2807     }
2808     var SecureRandom = /** @class */ (function () {
2809         function SecureRandom() {
2810         }
2811         SecureRandom.prototype.nextBytes = function (ba) {
2812             for (var i = 0; i < ba.length; ++i) {
2813                 ba[i] = rng_get_byte();
2814             }
2815         };
2816         return SecureRandom;
2817     }());
2818 
2819 // Depends on jsbn.js and rng.js
2820 // function linebrk(s,n) {
2821 //   var ret = "";
2822 //   var i = 0;
2823 //   while(i + n < s.length) {
2824 //     ret += s.substring(i,i+n) + "\n";
2825 //     i += n;
2826 //   }
2827 //   return ret + s.substring(i,s.length);
2828 // }
2829 // function byte2Hex(b) {
2830 //   if(b < 0x10)
2831 //     return "0" + b.toString(16);
2832 //   else
2833 //     return b.toString(16);
2834 // }
2835     function pkcs1pad1(s, n) {
2836         if (n < s.length + 22) {
2837             console.error("Message too long for RSA");
2838             return null;
2839         }
2840         var len = n - s.length - 6;
2841         var filler = "";
2842         for (var f = 0; f < len; f += 2) {
2843             filler += "ff";
2844         }
2845         var m = "0001" + filler + "00" + s;
2846         return parseBigInt(m, 16);
2847     }
2848 // PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
2849     function pkcs1pad2(s, n) {
2850         if (n < s.length + 11) { // TODO: fix for utf-8
2851             console.error("Message too long for RSA");
2852             return null;
2853         }
2854         var ba = [];
2855         var i = s.length - 1;
2856         while (i >= 0 && n > 0) {
2857             var c = s.charCodeAt(i--);
2858             if (c < 128) { // encode using utf-8
2859                 ba[--n] = c;
2860             }
2861             else if ((c > 127) && (c < 2048)) {
2862                 ba[--n] = (c & 63) | 128;
2863                 ba[--n] = (c >> 6) | 192;
2864             }
2865             else {
2866                 ba[--n] = (c & 63) | 128;
2867                 ba[--n] = ((c >> 6) & 63) | 128;
2868                 ba[--n] = (c >> 12) | 224;
2869             }
2870         }
2871         ba[--n] = 0;
2872         var rng = new SecureRandom();
2873         var x = [];
2874         while (n > 2) { // random non-zero pad
2875             x[0] = 0;
2876             while (x[0] == 0) {
2877                 rng.nextBytes(x);
2878             }
2879             ba[--n] = x[0];
2880         }
2881         ba[--n] = 2;
2882         ba[--n] = 0;
2883         return new BigInteger(ba);
2884     }
2885 // "empty" RSA key constructor
2886     var RSAKey = /** @class */ (function () {
2887         function RSAKey() {
2888             this.n = null;
2889             this.e = 0;
2890             this.d = null;
2891             this.p = null;
2892             this.q = null;
2893             this.dmp1 = null;
2894             this.dmq1 = null;
2895             this.coeff = null;
2896         }
2897         //#region PROTECTED
2898         // protected
2899         // RSAKey.prototype.doPublic = RSADoPublic;
2900         // Perform raw public operation on "x": return x^e (mod n)
2901         RSAKey.prototype.doPublic = function (x) {
2902             return x.modPowInt(this.e, this.n);
2903         };
2904         // RSAKey.prototype.doPrivate = RSADoPrivate;
2905         // Perform raw private operation on "x": return x^d (mod n)
2906         RSAKey.prototype.doPrivate = function (x) {
2907             if (this.p == null || this.q == null) {
2908                 return x.modPow(this.d, this.n);
2909             }
2910             // TODO: re-calculate any missing CRT params
2911             var xp = x.mod(this.p).modPow(this.dmp1, this.p);
2912             var xq = x.mod(this.q).modPow(this.dmq1, this.q);
2913             while (xp.compareTo(xq) < 0) {
2914                 xp = xp.add(this.p);
2915             }
2916             return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
2917         };
2918         //#endregion PROTECTED
2919         //#region PUBLIC
2920         // RSAKey.prototype.setPublic = RSASetPublic;
2921         // Set the public key fields N and e from hex strings
2922         RSAKey.prototype.setPublic = function (N, E) {
2923             if (N != null && E != null && N.length > 0 && E.length > 0) {
2924                 this.n = parseBigInt(N, 16);
2925                 this.e = parseInt(E, 16);
2926             }
2927             else {
2928                 console.error("Invalid RSA public key");
2929             }
2930         };
2931         // RSAKey.prototype.encrypt = RSAEncrypt;
2932         // Return the PKCS#1 RSA encryption of "text" as an even-length hex string
2933         RSAKey.prototype.encrypt = function (text) {
2934             var m = pkcs1pad2(text, (this.n.bitLength() + 7) >> 3);
2935             if (m == null) {
2936                 return null;
2937             }
2938             var c = this.doPublic(m);
2939             if (c == null) {
2940                 return null;
2941             }
2942             var h = c.toString(16);
2943             if ((h.length & 1) == 0) {
2944                 return h;
2945             }
2946             else {
2947                 return "0" + h;
2948             }
2949         };
2950         // RSAKey.prototype.setPrivate = RSASetPrivate;
2951         // Set the private key fields N, e, and d from hex strings
2952         RSAKey.prototype.setPrivate = function (N, E, D) {
2953             if (N != null && E != null && N.length > 0 && E.length > 0) {
2954                 this.n = parseBigInt(N, 16);
2955                 this.e = parseInt(E, 16);
2956                 this.d = parseBigInt(D, 16);
2957             }
2958             else {
2959                 console.error("Invalid RSA private key");
2960             }
2961         };
2962         // RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
2963         // Set the private key fields N, e, d and CRT params from hex strings
2964         RSAKey.prototype.setPrivateEx = function (N, E, D, P, Q, DP, DQ, C) {
2965             if (N != null && E != null && N.length > 0 && E.length > 0) {
2966                 this.n = parseBigInt(N, 16);
2967                 this.e = parseInt(E, 16);
2968                 this.d = parseBigInt(D, 16);
2969                 this.p = parseBigInt(P, 16);
2970                 this.q = parseBigInt(Q, 16);
2971                 this.dmp1 = parseBigInt(DP, 16);
2972                 this.dmq1 = parseBigInt(DQ, 16);
2973                 this.coeff = parseBigInt(C, 16);
2974             }
2975             else {
2976                 console.error("Invalid RSA private key");
2977             }
2978         };
2979         // RSAKey.prototype.generate = RSAGenerate;
2980         // Generate a new random private key B bits long, using public expt E
2981         RSAKey.prototype.generate = function (B, E) {
2982             var rng = new SecureRandom();
2983             var qs = B >> 1;
2984             this.e = parseInt(E, 16);
2985             var ee = new BigInteger(E, 16);
2986             for (;;) {
2987                 for (;;) {
2988                     this.p = new BigInteger(B - qs, 1, rng);
2989                     if (this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) {
2990                         break;
2991                     }
2992                 }
2993                 for (;;) {
2994                     this.q = new BigInteger(qs, 1, rng);
2995                     if (this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) {
2996                         break;
2997                     }
2998                 }
2999                 if (this.p.compareTo(this.q) <= 0) {
3000                     var t = this.p;
3001                     this.p = this.q;
3002                     this.q = t;
3003                 }
3004                 var p1 = this.p.subtract(BigInteger.ONE);
3005                 var q1 = this.q.subtract(BigInteger.ONE);
3006                 var phi = p1.multiply(q1);
3007                 if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
3008                     this.n = this.p.multiply(this.q);
3009                     this.d = ee.modInverse(phi);
3010                     this.dmp1 = this.d.mod(p1);
3011                     this.dmq1 = this.d.mod(q1);
3012                     this.coeff = this.q.modInverse(this.p);
3013                     break;
3014                 }
3015             }
3016         };
3017         // RSAKey.prototype.decrypt = RSADecrypt;
3018         // Return the PKCS#1 RSA decryption of "ctext".
3019         // "ctext" is an even-length hex string and the output is a plain string.
3020         RSAKey.prototype.decrypt = function (ctext) {
3021             var c = parseBigInt(ctext, 16);
3022             var m = this.doPrivate(c);
3023             if (m == null) {
3024                 return null;
3025             }
3026             return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
3027         };
3028         // Generate a new random private key B bits long, using public expt E
3029         RSAKey.prototype.generateAsync = function (B, E, callback) {
3030             var rng = new SecureRandom();
3031             var qs = B >> 1;
3032             this.e = parseInt(E, 16);
3033             var ee = new BigInteger(E, 16);
3034             var rsa = this;
3035             // These functions have non-descript names because they were originally for(;;) loops.
3036             // I don't know about cryptography to give them better names than loop1-4.
3037             var loop1 = function () {
3038                 var loop4 = function () {
3039                     if (rsa.p.compareTo(rsa.q) <= 0) {
3040                         var t = rsa.p;
3041                         rsa.p = rsa.q;
3042                         rsa.q = t;
3043                     }
3044                     var p1 = rsa.p.subtract(BigInteger.ONE);
3045                     var q1 = rsa.q.subtract(BigInteger.ONE);
3046                     var phi = p1.multiply(q1);
3047                     if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
3048                         rsa.n = rsa.p.multiply(rsa.q);
3049                         rsa.d = ee.modInverse(phi);
3050                         rsa.dmp1 = rsa.d.mod(p1);
3051                         rsa.dmq1 = rsa.d.mod(q1);
3052                         rsa.coeff = rsa.q.modInverse(rsa.p);
3053                         setTimeout(function () { callback(); }, 0); // escape
3054                     }
3055                     else {
3056                         setTimeout(loop1, 0);
3057                     }
3058                 };
3059                 var loop3 = function () {
3060                     rsa.q = nbi();
3061                     rsa.q.fromNumberAsync(qs, 1, rng, function () {
3062                         rsa.q.subtract(BigInteger.ONE).gcda(ee, function (r) {
3063                             if (r.compareTo(BigInteger.ONE) == 0 && rsa.q.isProbablePrime(10)) {
3064                                 setTimeout(loop4, 0);
3065                             }
3066                             else {
3067                                 setTimeout(loop3, 0);
3068                             }
3069                         });
3070                     });
3071                 };
3072                 var loop2 = function () {
3073                     rsa.p = nbi();
3074                     rsa.p.fromNumberAsync(B - qs, 1, rng, function () {
3075                         rsa.p.subtract(BigInteger.ONE).gcda(ee, function (r) {
3076                             if (r.compareTo(BigInteger.ONE) == 0 && rsa.p.isProbablePrime(10)) {
3077                                 setTimeout(loop3, 0);
3078                             }
3079                             else {
3080                                 setTimeout(loop2, 0);
3081                             }
3082                         });
3083                     });
3084                 };
3085                 setTimeout(loop2, 0);
3086             };
3087             setTimeout(loop1, 0);
3088         };
3089         RSAKey.prototype.sign = function (text, digestMethod, digestName) {
3090             var header = getDigestHeader(digestName);
3091             var digest = header + digestMethod(text).toString();
3092             var m = pkcs1pad1(digest, this.n.bitLength() / 4);
3093             if (m == null) {
3094                 return null;
3095             }
3096             var c = this.doPrivate(m);
3097             if (c == null) {
3098                 return null;
3099             }
3100             var h = c.toString(16);
3101             if ((h.length & 1) == 0) {
3102                 return h;
3103             }
3104             else {
3105                 return "0" + h;
3106             }
3107         };
3108         RSAKey.prototype.verify = function (text, signature, digestMethod) {
3109             var c = parseBigInt(signature, 16);
3110             var m = this.doPublic(c);
3111             if (m == null) {
3112                 return null;
3113             }
3114             var unpadded = m.toString(16).replace(/^1f+00/, "");
3115             var digest = removeDigestHeader(unpadded);
3116             return digest == digestMethod(text).toString();
3117         };
3118         return RSAKey;
3119     }());
3120 // Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
3121     function pkcs1unpad2(d, n) {
3122         var b = d.toByteArray();
3123         var i = 0;
3124         while (i < b.length && b[i] == 0) {
3125             ++i;
3126         }
3127         if (b.length - i != n - 1 || b[i] != 2) {
3128             return null;
3129         }
3130         ++i;
3131         while (b[i] != 0) {
3132             if (++i >= b.length) {
3133                 return null;
3134             }
3135         }
3136         var ret = "";
3137         while (++i < b.length) {
3138             var c = b[i] & 255;
3139             if (c < 128) { // utf-8 decode
3140                 ret += String.fromCharCode(c);
3141             }
3142             else if ((c > 191) && (c < 224)) {
3143                 ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63));
3144                 ++i;
3145             }
3146             else {
3147                 ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63));
3148                 i += 2;
3149             }
3150         }
3151         return ret;
3152     }
3153 // https://tools.ietf.org/html/rfc3447#page-43
3154     var DIGEST_HEADERS = {
3155         md2: "3020300c06082a864886f70d020205000410",
3156         md5: "3020300c06082a864886f70d020505000410",
3157         sha1: "3021300906052b0e03021a05000414",
3158         sha224: "302d300d06096086480165030402040500041c",
3159         sha256: "3031300d060960864801650304020105000420",
3160         sha384: "3041300d060960864801650304020205000430",
3161         sha512: "3051300d060960864801650304020305000440",
3162         ripemd160: "3021300906052b2403020105000414",
3163     };
3164     function getDigestHeader(name) {
3165         return DIGEST_HEADERS[name] || "";
3166     }
3167     function removeDigestHeader(str) {
3168         for (var name_1 in DIGEST_HEADERS) {
3169             if (DIGEST_HEADERS.hasOwnProperty(name_1)) {
3170                 var header = DIGEST_HEADERS[name_1];
3171                 var len = header.length;
3172                 if (str.substr(0, len) == header) {
3173                     return str.substr(len);
3174                 }
3175             }
3176         }
3177         return str;
3178     }
3179 // Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
3180 // function RSAEncryptB64(text) {
3181 //  var h = this.encrypt(text);
3182 //  if(h) return hex2b64(h); else return null;
3183 // }
3184 // public
3185 // RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
3186 
3187     /*!
3188 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
3189 Code licensed under the BSD License:
3190 http://developer.yahoo.com/yui/license.html
3191 version: 2.9.0
3192 */
3193     var YAHOO = {};
3194     YAHOO.lang = {
3195         /**
3196          * Utility to set up the prototype, constructor and superclass properties to
3197          * support an inheritance strategy that can chain constructors and methods.
3198          * Static members will not be inherited.
3199          *
3200          * @method extend
3201          * @static
3202          * @param {Function} subc   the object to modify
3203          * @param {Function} superc the object to inherit
3204          * @param {Object} overrides  additional properties/methods to add to the
3205          *                              subclass prototype.  These will override the
3206          *                              matching items obtained from the superclass
3207          *                              if present.
3208          */
3209         extend: function(subc, superc, overrides) {
3210             if (! superc || ! subc) {
3211                 throw new Error("YAHOO.lang.extend failed, please check that " +
3212                     "all dependencies are included.");
3213             }
3214 
3215             var F = function() {};
3216             F.prototype = superc.prototype;
3217             subc.prototype = new F();
3218             subc.prototype.constructor = subc;
3219             subc.superclass = superc.prototype;
3220 
3221             if (superc.prototype.constructor == Object.prototype.constructor) {
3222                 superc.prototype.constructor = superc;
3223             }
3224 
3225             if (overrides) {
3226                 var i;
3227                 for (i in overrides) {
3228                     subc.prototype[i] = overrides[i];
3229                 }
3230 
3231                 /*
3232              * IE will not enumerate native functions in a derived object even if the
3233              * function was overridden.  This is a workaround for specific functions
3234              * we care about on the Object prototype.
3235              * @property _IEEnumFix
3236              * @param {Function} r  the object to receive the augmentation
3237              * @param {Function} s  the object that supplies the properties to augment
3238              * @static
3239              * @private
3240              */
3241                 var _IEEnumFix = function() {},
3242                     ADD = ["toString", "valueOf"];
3243                 try {
3244                     if (/MSIE/.test(navigator.userAgent)) {
3245                         _IEEnumFix = function(r, s) {
3246                             for (i = 0; i < ADD.length; i = i + 1) {
3247                                 var fname = ADD[i], f = s[fname];
3248                                 if (typeof f === 'function' && f != Object.prototype[fname]) {
3249                                     r[fname] = f;
3250                                 }
3251                             }
3252                         };
3253                     }
3254                 } catch (ex) {}            _IEEnumFix(subc.prototype, overrides);
3255             }
3256         }
3257     };
3258 
3259     /* asn1-1.0.13.js (c) 2013-2017 Kenji Urushima | kjur.github.com/jsrsasign/license
3260  */
3261 
3262     /**
3263      * @fileOverview
3264      * @name asn1-1.0.js
3265      * @author Kenji Urushima kenji.urushima@gmail.com
3266      * @version asn1 1.0.13 (2017-Jun-02)
3267      * @since jsrsasign 2.1
3268      * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
3269      */
3270 
3271     /**
3272      * kjur's class library name space
3273      * <p>
3274      * This name space provides following name spaces:
3275      * <ul>
3276      * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li>
3277      * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li>
3278      * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature
3279      * class and utilities</li>
3280      * </ul>
3281      * </p>
3282      * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
3283      * @name KJUR
3284      * @namespace kjur's class library name space
3285      */
3286     var KJUR = {};
3287 
3288     /**
3289      * kjur's ASN.1 class library name space
3290      * <p>
3291      * This is ITU-T X.690 ASN.1 DER encoder class library and
3292      * class structure and methods is very similar to
3293      * org.bouncycastle.asn1 package of
3294      * well known BouncyCaslte Cryptography Library.
3295      * <h4>PROVIDING ASN.1 PRIMITIVES</h4>
3296      * Here are ASN.1 DER primitive classes.
3297      * <ul>
3298      * <li>0x01 {@link KJUR.asn1.DERBoolean}</li>
3299      * <li>0x02 {@link KJUR.asn1.DERInteger}</li>
3300      * <li>0x03 {@link KJUR.asn1.DERBitString}</li>
3301      * <li>0x04 {@link KJUR.asn1.DEROctetString}</li>
3302      * <li>0x05 {@link KJUR.asn1.DERNull}</li>
3303      * <li>0x06 {@link KJUR.asn1.DERObjectIdentifier}</li>
3304      * <li>0x0a {@link KJUR.asn1.DEREnumerated}</li>
3305      * <li>0x0c {@link KJUR.asn1.DERUTF8String}</li>
3306      * <li>0x12 {@link KJUR.asn1.DERNumericString}</li>
3307      * <li>0x13 {@link KJUR.asn1.DERPrintableString}</li>
3308      * <li>0x14 {@link KJUR.asn1.DERTeletexString}</li>
3309      * <li>0x16 {@link KJUR.asn1.DERIA5String}</li>
3310      * <li>0x17 {@link KJUR.asn1.DERUTCTime}</li>
3311      * <li>0x18 {@link KJUR.asn1.DERGeneralizedTime}</li>
3312      * <li>0x30 {@link KJUR.asn1.DERSequence}</li>
3313      * <li>0x31 {@link KJUR.asn1.DERSet}</li>
3314      * </ul>
3315      * <h4>OTHER ASN.1 CLASSES</h4>
3316      * <ul>
3317      * <li>{@link KJUR.asn1.ASN1Object}</li>
3318      * <li>{@link KJUR.asn1.DERAbstractString}</li>
3319      * <li>{@link KJUR.asn1.DERAbstractTime}</li>
3320      * <li>{@link KJUR.asn1.DERAbstractStructured}</li>
3321      * <li>{@link KJUR.asn1.DERTaggedObject}</li>
3322      * </ul>
3323      * <h4>SUB NAME SPACES</h4>
3324      * <ul>
3325      * <li>{@link KJUR.asn1.cades} - CAdES long term signature format</li>
3326      * <li>{@link KJUR.asn1.cms} - Cryptographic Message Syntax</li>
3327      * <li>{@link KJUR.asn1.csr} - Certificate Signing Request (CSR/PKCS#10)</li>
3328      * <li>{@link KJUR.asn1.tsp} - RFC 3161 Timestamping Protocol Format</li>
3329      * <li>{@link KJUR.asn1.x509} - RFC 5280 X.509 certificate and CRL</li>
3330      * </ul>
3331      * </p>
3332      * NOTE: Please ignore method summary and document of this namespace.
3333      * This caused by a bug of jsdoc2.
3334      * @name KJUR.asn1
3335      * @namespace
3336      */
3337     if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
3338 
3339     /**
3340      * ASN1 utilities class
3341      * @name KJUR.asn1.ASN1Util
3342      * @class ASN1 utilities class
3343      * @since asn1 1.0.2
3344      */
3345     KJUR.asn1.ASN1Util = new function() {
3346         this.integerToByteHex = function(i) {
3347             var h = i.toString(16);
3348             if ((h.length % 2) == 1) h = '0' + h;
3349             return h;
3350         };
3351         this.bigIntToMinTwosComplementsHex = function(bigIntegerValue) {
3352             var h = bigIntegerValue.toString(16);
3353             if (h.substr(0, 1) != '-') {
3354                 if (h.length % 2 == 1) {
3355                     h = '0' + h;
3356                 } else {
3357                     if (! h.match(/^[0-7]/)) {
3358                         h = '00' + h;
3359                     }
3360                 }
3361             } else {
3362                 var hPos = h.substr(1);
3363                 var xorLen = hPos.length;
3364                 if (xorLen % 2 == 1) {
3365                     xorLen += 1;
3366                 } else {
3367                     if (! h.match(/^[0-7]/)) {
3368                         xorLen += 2;
3369                     }
3370                 }
3371                 var hMask = '';
3372                 for (var i = 0; i < xorLen; i++) {
3373                     hMask += 'f';
3374                 }
3375                 var biMask = new BigInteger(hMask, 16);
3376                 var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE);
3377                 h = biNeg.toString(16).replace(/^-/, '');
3378             }
3379             return h;
3380         };
3381         /**
3382          * get PEM string from hexadecimal data and header string
3383          * @name getPEMStringFromHex
3384          * @memberOf KJUR.asn1.ASN1Util
3385          * @function
3386          * @param {String} dataHex hexadecimal string of PEM body
3387          * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY')
3388          * @return {String} PEM formatted string of input data
3389          * @description
3390          * This method converts a hexadecimal string to a PEM string with
3391          * a specified header. Its line break will be CRLF("\r\n").
3392          * @example
3393          * var pem  = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY');
3394          * // value of pem will be:
3395          * -----BEGIN PRIVATE KEY-----
3396          * YWFh
3397          * -----END PRIVATE KEY-----
3398          */
3399         this.getPEMStringFromHex = function(dataHex, pemHeader) {
3400             return hextopem(dataHex, pemHeader);
3401         };
3402 
3403         /**
3404          * generate ASN1Object specifed by JSON parameters
3405          * @name newObject
3406          * @memberOf KJUR.asn1.ASN1Util
3407          * @function
3408          * @param {Array} param JSON parameter to generate ASN1Object
3409          * @return {KJUR.asn1.ASN1Object} generated object
3410          * @since asn1 1.0.3
3411          * @description
3412          * generate any ASN1Object specified by JSON param
3413          * including ASN.1 primitive or structured.
3414          * Generally 'param' can be described as follows:
3415          * <blockquote>
3416          * {TYPE-OF-ASNOBJ: ASN1OBJ-PARAMETER}
3417          * </blockquote>
3418          * 'TYPE-OF-ASN1OBJ' can be one of following symbols:
3419          * <ul>
3420          * <li>'bool' - DERBoolean</li>
3421          * <li>'int' - DERInteger</li>
3422          * <li>'bitstr' - DERBitString</li>
3423          * <li>'octstr' - DEROctetString</li>
3424          * <li>'null' - DERNull</li>
3425          * <li>'oid' - DERObjectIdentifier</li>
3426          * <li>'enum' - DEREnumerated</li>
3427          * <li>'utf8str' - DERUTF8String</li>
3428          * <li>'numstr' - DERNumericString</li>
3429          * <li>'prnstr' - DERPrintableString</li>
3430          * <li>'telstr' - DERTeletexString</li>
3431          * <li>'ia5str' - DERIA5String</li>
3432          * <li>'utctime' - DERUTCTime</li>
3433          * <li>'gentime' - DERGeneralizedTime</li>
3434          * <li>'seq' - DERSequence</li>
3435          * <li>'set' - DERSet</li>
3436          * <li>'tag' - DERTaggedObject</li>
3437          * </ul>
3438          * @example
3439          * newObject({'prnstr': 'aaa'});
3440          * newObject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]})
3441          * // ASN.1 Tagged Object
3442          * newObject({'tag': {'tag': 'a1',
3443          *                    'explicit': true,
3444          *                    'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}});
3445          * // more simple representation of ASN.1 Tagged Object
3446          * newObject({'tag': ['a1',
3447          *                    true,
3448          *                    {'seq': [
3449          *                      {'int': 3},
3450          *                      {'prnstr': 'aaa'}]}
3451          *                   ]});
3452          */
3453         this.newObject = function(param) {
3454             var _KJUR = KJUR,
3455                 _KJUR_asn1 = _KJUR.asn1,
3456                 _DERBoolean = _KJUR_asn1.DERBoolean,
3457                 _DERInteger = _KJUR_asn1.DERInteger,
3458                 _DERBitString = _KJUR_asn1.DERBitString,
3459                 _DEROctetString = _KJUR_asn1.DEROctetString,
3460                 _DERNull = _KJUR_asn1.DERNull,
3461                 _DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
3462                 _DEREnumerated = _KJUR_asn1.DEREnumerated,
3463                 _DERUTF8String = _KJUR_asn1.DERUTF8String,
3464                 _DERNumericString = _KJUR_asn1.DERNumericString,
3465                 _DERPrintableString = _KJUR_asn1.DERPrintableString,
3466                 _DERTeletexString = _KJUR_asn1.DERTeletexString,
3467                 _DERIA5String = _KJUR_asn1.DERIA5String,
3468                 _DERUTCTime = _KJUR_asn1.DERUTCTime,
3469                 _DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime,
3470                 _DERSequence = _KJUR_asn1.DERSequence,
3471                 _DERSet = _KJUR_asn1.DERSet,
3472                 _DERTaggedObject = _KJUR_asn1.DERTaggedObject,
3473                 _newObject = _KJUR_asn1.ASN1Util.newObject;
3474 
3475             var keys = Object.keys(param);
3476             if (keys.length != 1)
3477                 throw "key of param shall be only one.";
3478             var key = keys[0];
3479 
3480             if (":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:".indexOf(":" + key + ":") == -1)
3481                 throw "undefined key: " + key;
3482 
3483             if (key == "bool")    return new _DERBoolean(param[key]);
3484             if (key == "int")     return new _DERInteger(param[key]);
3485             if (key == "bitstr")  return new _DERBitString(param[key]);
3486             if (key == "octstr")  return new _DEROctetString(param[key]);
3487             if (key == "null")    return new _DERNull(param[key]);
3488             if (key == "oid")     return new _DERObjectIdentifier(param[key]);
3489             if (key == "enum")    return new _DEREnumerated(param[key]);
3490             if (key == "utf8str") return new _DERUTF8String(param[key]);
3491             if (key == "numstr")  return new _DERNumericString(param[key]);
3492             if (key == "prnstr")  return new _DERPrintableString(param[key]);
3493             if (key == "telstr")  return new _DERTeletexString(param[key]);
3494             if (key == "ia5str")  return new _DERIA5String(param[key]);
3495             if (key == "utctime") return new _DERUTCTime(param[key]);
3496             if (key == "gentime") return new _DERGeneralizedTime(param[key]);
3497 
3498             if (key == "seq") {
3499                 var paramList = param[key];
3500                 var a = [];
3501                 for (var i = 0; i < paramList.length; i++) {
3502                     var asn1Obj = _newObject(paramList[i]);
3503                     a.push(asn1Obj);
3504                 }
3505                 return new _DERSequence({'array': a});
3506             }
3507 
3508             if (key == "set") {
3509                 var paramList = param[key];
3510                 var a = [];
3511                 for (var i = 0; i < paramList.length; i++) {
3512                     var asn1Obj = _newObject(paramList[i]);
3513                     a.push(asn1Obj);
3514                 }
3515                 return new _DERSet({'array': a});
3516             }
3517 
3518             if (key == "tag") {
3519                 var tagParam = param[key];
3520                 if (Object.prototype.toString.call(tagParam) === '[object Array]' &&
3521                     tagParam.length == 3) {
3522                     var obj = _newObject(tagParam[2]);
3523                     return new _DERTaggedObject({tag: tagParam[0],
3524                         explicit: tagParam[1],
3525                         obj: obj});
3526                 } else {
3527                     var newParam = {};
3528                     if (tagParam.explicit !== undefined)
3529                         newParam.explicit = tagParam.explicit;
3530                     if (tagParam.tag !== undefined)
3531                         newParam.tag = tagParam.tag;
3532                     if (tagParam.obj === undefined)
3533                         throw "obj shall be specified for 'tag'.";
3534                     newParam.obj = _newObject(tagParam.obj);
3535                     return new _DERTaggedObject(newParam);
3536                 }
3537             }
3538         };
3539 
3540         /**
3541          * get encoded hexadecimal string of ASN1Object specifed by JSON parameters
3542          * @name jsonToASN1HEX
3543          * @memberOf KJUR.asn1.ASN1Util
3544          * @function
3545          * @param {Array} param JSON parameter to generate ASN1Object
3546          * @return hexadecimal string of ASN1Object
3547          * @since asn1 1.0.4
3548          * @description
3549          * As for ASN.1 object representation of JSON object,
3550          * please see {@link newObject}.
3551          * @example
3552          * jsonToASN1HEX({'prnstr': 'aaa'});
3553          */
3554         this.jsonToASN1HEX = function(param) {
3555             var asn1Obj = this.newObject(param);
3556             return asn1Obj.getEncodedHex();
3557         };
3558     };
3559 
3560     /**
3561      * get dot noted oid number string from hexadecimal value of OID
3562      * @name oidHexToInt
3563      * @memberOf KJUR.asn1.ASN1Util
3564      * @function
3565      * @param {String} hex hexadecimal value of object identifier
3566      * @return {String} dot noted string of object identifier
3567      * @since jsrsasign 4.8.3 asn1 1.0.7
3568      * @description
3569      * This static method converts from hexadecimal string representation of
3570      * ASN.1 value of object identifier to oid number string.
3571      * @example
3572      * KJUR.asn1.ASN1Util.oidHexToInt('550406') &rarr; "2.5.4.6"
3573      */
3574     KJUR.asn1.ASN1Util.oidHexToInt = function(hex) {
3575         var s = "";
3576         var i01 = parseInt(hex.substr(0, 2), 16);
3577         var i0 = Math.floor(i01 / 40);
3578         var i1 = i01 % 40;
3579         var s = i0 + "." + i1;
3580 
3581         var binbuf = "";
3582         for (var i = 2; i < hex.length; i += 2) {
3583             var value = parseInt(hex.substr(i, 2), 16);
3584             var bin = ("00000000" + value.toString(2)).slice(- 8);
3585             binbuf = binbuf + bin.substr(1, 7);
3586             if (bin.substr(0, 1) == "0") {
3587                 var bi = new BigInteger(binbuf, 2);
3588                 s = s + "." + bi.toString(10);
3589                 binbuf = "";
3590             }
3591         }
3592         return s;
3593     };
3594 
3595     /**
3596      * get hexadecimal value of object identifier from dot noted oid value
3597      * @name oidIntToHex
3598      * @memberOf KJUR.asn1.ASN1Util
3599      * @function
3600      * @param {String} oidString dot noted string of object identifier
3601      * @return {String} hexadecimal value of object identifier
3602      * @since jsrsasign 4.8.3 asn1 1.0.7
3603      * @description
3604      * This static method converts from object identifier value string.
3605      * to hexadecimal string representation of it.
3606      * @example
3607      * KJUR.asn1.ASN1Util.oidIntToHex("2.5.4.6") &rarr; "550406"
3608      */
3609     KJUR.asn1.ASN1Util.oidIntToHex = function(oidString) {
3610         var itox = function(i) {
3611             var h = i.toString(16);
3612             if (h.length == 1) h = '0' + h;
3613             return h;
3614         };
3615 
3616         var roidtox = function(roid) {
3617             var h = '';
3618             var bi = new BigInteger(roid, 10);
3619             var b = bi.toString(2);
3620             var padLen = 7 - b.length % 7;
3621             if (padLen == 7) padLen = 0;
3622             var bPad = '';
3623             for (var i = 0; i < padLen; i++) bPad += '0';
3624             b = bPad + b;
3625             for (var i = 0; i < b.length - 1; i += 7) {
3626                 var b8 = b.substr(i, 7);
3627                 if (i != b.length - 7) b8 = '1' + b8;
3628                 h += itox(parseInt(b8, 2));
3629             }
3630             return h;
3631         };
3632 
3633         if (! oidString.match(/^[0-9.]+$/)) {
3634             throw "malformed oid string: " + oidString;
3635         }
3636         var h = '';
3637         var a = oidString.split('.');
3638         var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
3639         h += itox(i0);
3640         a.splice(0, 2);
3641         for (var i = 0; i < a.length; i++) {
3642             h += roidtox(a[i]);
3643         }
3644         return h;
3645     };
3646 
3647 
3648 // ********************************************************************
3649 //  Abstract ASN.1 Classes
3650 // ********************************************************************
3651 
3652 // ********************************************************************
3653 
3654     /**
3655      * base class for ASN.1 DER encoder object
3656      * @name KJUR.asn1.ASN1Object
3657      * @class base class for ASN.1 DER encoder object
3658      * @property {Boolean} isModified flag whether internal data was changed
3659      * @property {String} hTLV hexadecimal string of ASN.1 TLV
3660      * @property {String} hT hexadecimal string of ASN.1 TLV tag(T)
3661      * @property {String} hL hexadecimal string of ASN.1 TLV length(L)
3662      * @property {String} hV hexadecimal string of ASN.1 TLV value(V)
3663      * @description
3664      */
3665     KJUR.asn1.ASN1Object = function() {
3666         var hV = '';
3667 
3668         /**
3669          * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V)
3670          * @name getLengthHexFromValue
3671          * @memberOf KJUR.asn1.ASN1Object#
3672          * @function
3673          * @return {String} hexadecimal string of ASN.1 TLV length(L)
3674          */
3675         this.getLengthHexFromValue = function() {
3676             if (typeof this.hV == "undefined" || this.hV == null) {
3677                 throw "this.hV is null or undefined.";
3678             }
3679             if (this.hV.length % 2 == 1) {
3680                 throw "value hex must be even length: n=" + hV.length + ",v=" + this.hV;
3681             }
3682             var n = this.hV.length / 2;
3683             var hN = n.toString(16);
3684             if (hN.length % 2 == 1) {
3685                 hN = "0" + hN;
3686             }
3687             if (n < 128) {
3688                 return hN;
3689             } else {
3690                 var hNlen = hN.length / 2;
3691                 if (hNlen > 15) {
3692                     throw "ASN.1 length too long to represent by 8x: n = " + n.toString(16);
3693                 }
3694                 var head = 128 + hNlen;
3695                 return head.toString(16) + hN;
3696             }
3697         };
3698 
3699         /**
3700          * get hexadecimal string of ASN.1 TLV bytes
3701          * @name getEncodedHex
3702          * @memberOf KJUR.asn1.ASN1Object#
3703          * @function
3704          * @return {String} hexadecimal string of ASN.1 TLV
3705          */
3706         this.getEncodedHex = function() {
3707             if (this.hTLV == null || this.isModified) {
3708                 this.hV = this.getFreshValueHex();
3709                 this.hL = this.getLengthHexFromValue();
3710                 this.hTLV = this.hT + this.hL + this.hV;
3711                 this.isModified = false;
3712                 //alert("first time: " + this.hTLV);
3713             }
3714             return this.hTLV;
3715         };
3716 
3717         /**
3718          * get hexadecimal string of ASN.1 TLV value(V) bytes
3719          * @name getValueHex
3720          * @memberOf KJUR.asn1.ASN1Object#
3721          * @function
3722          * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes
3723          */
3724         this.getValueHex = function() {
3725             this.getEncodedHex();
3726             return this.hV;
3727         };
3728 
3729         this.getFreshValueHex = function() {
3730             return '';
3731         };
3732     };
3733 
3734 // == BEGIN DERAbstractString ================================================
3735     /**
3736      * base class for ASN.1 DER string classes
3737      * @name KJUR.asn1.DERAbstractString
3738      * @class base class for ASN.1 DER string classes
3739      * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
3740      * @property {String} s internal string of value
3741      * @extends KJUR.asn1.ASN1Object
3742      * @description
3743      * <br/>
3744      * As for argument 'params' for constructor, you can specify one of
3745      * following properties:
3746      * <ul>
3747      * <li>str - specify initial ASN.1 value(V) by a string</li>
3748      * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
3749      * </ul>
3750      * NOTE: 'params' can be omitted.
3751      */
3752     KJUR.asn1.DERAbstractString = function(params) {
3753         KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
3754 
3755         /**
3756          * get string value of this string object
3757          * @name getString
3758          * @memberOf KJUR.asn1.DERAbstractString#
3759          * @function
3760          * @return {String} string value of this string object
3761          */
3762         this.getString = function() {
3763             return this.s;
3764         };
3765 
3766         /**
3767          * set value by a string
3768          * @name setString
3769          * @memberOf KJUR.asn1.DERAbstractString#
3770          * @function
3771          * @param {String} newS value by a string to set
3772          */
3773         this.setString = function(newS) {
3774             this.hTLV = null;
3775             this.isModified = true;
3776             this.s = newS;
3777             this.hV = stohex(this.s);
3778         };
3779 
3780         /**
3781          * set value by a hexadecimal string
3782          * @name setStringHex
3783          * @memberOf KJUR.asn1.DERAbstractString#
3784          * @function
3785          * @param {String} newHexString value by a hexadecimal string to set
3786          */
3787         this.setStringHex = function(newHexString) {
3788             this.hTLV = null;
3789             this.isModified = true;
3790             this.s = null;
3791             this.hV = newHexString;
3792         };
3793 
3794         this.getFreshValueHex = function() {
3795             return this.hV;
3796         };
3797 
3798         if (typeof params != "undefined") {
3799             if (typeof params == "string") {
3800                 this.setString(params);
3801             } else if (typeof params['str'] != "undefined") {
3802                 this.setString(params['str']);
3803             } else if (typeof params['hex'] != "undefined") {
3804                 this.setStringHex(params['hex']);
3805             }
3806         }
3807     };
3808     YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);
3809 // == END   DERAbstractString ================================================
3810 
3811 // == BEGIN DERAbstractTime ==================================================
3812     /**
3813      * base class for ASN.1 DER Generalized/UTCTime class
3814      * @name KJUR.asn1.DERAbstractTime
3815      * @class base class for ASN.1 DER Generalized/UTCTime class
3816      * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
3817      * @extends KJUR.asn1.ASN1Object
3818      * @description
3819      * @see KJUR.asn1.ASN1Object - superclass
3820      */
3821     KJUR.asn1.DERAbstractTime = function(params) {
3822         KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);
3823 
3824         // --- PRIVATE METHODS --------------------
3825         this.localDateToUTC = function(d) {
3826             utc = d.getTime() + (d.getTimezoneOffset() * 60000);
3827             var utcDate = new Date(utc);
3828             return utcDate;
3829         };
3830 
3831         /*
3832      * format date string by Data object
3833      * @name formatDate
3834      * @memberOf KJUR.asn1.AbstractTime;
3835      * @param {Date} dateObject
3836      * @param {string} type 'utc' or 'gen'
3837      * @param {boolean} withMillis flag for with millisections or not
3838      * @description
3839      * 'withMillis' flag is supported from asn1 1.0.6.
3840      */
3841         this.formatDate = function(dateObject, type, withMillis) {
3842             var pad = this.zeroPadding;
3843             var d = this.localDateToUTC(dateObject);
3844             var year = String(d.getFullYear());
3845             if (type == 'utc') year = year.substr(2, 2);
3846             var month = pad(String(d.getMonth() + 1), 2);
3847             var day = pad(String(d.getDate()), 2);
3848             var hour = pad(String(d.getHours()), 2);
3849             var min = pad(String(d.getMinutes()), 2);
3850             var sec = pad(String(d.getSeconds()), 2);
3851             var s = year + month + day + hour + min + sec;
3852             if (withMillis === true) {
3853                 var millis = d.getMilliseconds();
3854                 if (millis != 0) {
3855                     var sMillis = pad(String(millis), 3);
3856                     sMillis = sMillis.replace(/[0]+$/, "");
3857                     s = s + "." + sMillis;
3858                 }
3859             }
3860             return s + "Z";
3861         };
3862 
3863         this.zeroPadding = function(s, len) {
3864             if (s.length >= len) return s;
3865             return new Array(len - s.length + 1).join('0') + s;
3866         };
3867 
3868         // --- PUBLIC METHODS --------------------
3869         /**
3870          * get string value of this string object
3871          * @name getString
3872          * @memberOf KJUR.asn1.DERAbstractTime#
3873          * @function
3874          * @return {String} string value of this time object
3875          */
3876         this.getString = function() {
3877             return this.s;
3878         };
3879 
3880         /**
3881          * set value by a string
3882          * @name setString
3883          * @memberOf KJUR.asn1.DERAbstractTime#
3884          * @function
3885          * @param {String} newS value by a string to set such like "130430235959Z"
3886          */
3887         this.setString = function(newS) {
3888             this.hTLV = null;
3889             this.isModified = true;
3890             this.s = newS;
3891             this.hV = stohex(newS);
3892         };
3893 
3894         /**
3895          * set value by a Date object
3896          * @name setByDateValue
3897          * @memberOf KJUR.asn1.DERAbstractTime#
3898          * @function
3899          * @param {Integer} year year of date (ex. 2013)
3900          * @param {Integer} month month of date between 1 and 12 (ex. 12)
3901          * @param {Integer} day day of month
3902          * @param {Integer} hour hours of date
3903          * @param {Integer} min minutes of date
3904          * @param {Integer} sec seconds of date
3905          */
3906         this.setByDateValue = function(year, month, day, hour, min, sec) {
3907             var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));
3908             this.setByDate(dateObject);
3909         };
3910 
3911         this.getFreshValueHex = function() {
3912             return this.hV;
3913         };
3914     };
3915     YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);
3916 // == END   DERAbstractTime ==================================================
3917 
3918 // == BEGIN DERAbstractStructured ============================================
3919     /**
3920      * base class for ASN.1 DER structured class
3921      * @name KJUR.asn1.DERAbstractStructured
3922      * @class base class for ASN.1 DER structured class
3923      * @property {Array} asn1Array internal array of ASN1Object
3924      * @extends KJUR.asn1.ASN1Object
3925      * @description
3926      * @see KJUR.asn1.ASN1Object - superclass
3927      */
3928     KJUR.asn1.DERAbstractStructured = function(params) {
3929         KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
3930 
3931         /**
3932          * set value by array of ASN1Object
3933          * @name setByASN1ObjectArray
3934          * @memberOf KJUR.asn1.DERAbstractStructured#
3935          * @function
3936          * @param {array} asn1ObjectArray array of ASN1Object to set
3937          */
3938         this.setByASN1ObjectArray = function(asn1ObjectArray) {
3939             this.hTLV = null;
3940             this.isModified = true;
3941             this.asn1Array = asn1ObjectArray;
3942         };
3943 
3944         /**
3945          * append an ASN1Object to internal array
3946          * @name appendASN1Object
3947          * @memberOf KJUR.asn1.DERAbstractStructured#
3948          * @function
3949          * @param {ASN1Object} asn1Object to add
3950          */
3951         this.appendASN1Object = function(asn1Object) {
3952             this.hTLV = null;
3953             this.isModified = true;
3954             this.asn1Array.push(asn1Object);
3955         };
3956 
3957         this.asn1Array = new Array();
3958         if (typeof params != "undefined") {
3959             if (typeof params['array'] != "undefined") {
3960                 this.asn1Array = params['array'];
3961             }
3962         }
3963     };
3964     YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);
3965 
3966 
3967 // ********************************************************************
3968 //  ASN.1 Object Classes
3969 // ********************************************************************
3970 
3971 // ********************************************************************
3972     /**
3973      * class for ASN.1 DER Boolean
3974      * @name KJUR.asn1.DERBoolean
3975      * @class class for ASN.1 DER Boolean
3976      * @extends KJUR.asn1.ASN1Object
3977      * @description
3978      * @see KJUR.asn1.ASN1Object - superclass
3979      */
3980     KJUR.asn1.DERBoolean = function() {
3981         KJUR.asn1.DERBoolean.superclass.constructor.call(this);
3982         this.hT = "01";
3983         this.hTLV = "0101ff";
3984     };
3985     YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);
3986 
3987 // ********************************************************************
3988     /**
3989      * class for ASN.1 DER Integer
3990      * @name KJUR.asn1.DERInteger
3991      * @class class for ASN.1 DER Integer
3992      * @extends KJUR.asn1.ASN1Object
3993      * @description
3994      * <br/>
3995      * As for argument 'params' for constructor, you can specify one of
3996      * following properties:
3997      * <ul>
3998      * <li>int - specify initial ASN.1 value(V) by integer value</li>
3999      * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li>
4000      * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
4001      * </ul>
4002      * NOTE: 'params' can be omitted.
4003      */
4004     KJUR.asn1.DERInteger = function(params) {
4005         KJUR.asn1.DERInteger.superclass.constructor.call(this);
4006         this.hT = "02";
4007 
4008         /**
4009          * set value by Tom Wu's BigInteger object
4010          * @name setByBigInteger
4011          * @memberOf KJUR.asn1.DERInteger#
4012          * @function
4013          * @param {BigInteger} bigIntegerValue to set
4014          */
4015         this.setByBigInteger = function(bigIntegerValue) {
4016             this.hTLV = null;
4017             this.isModified = true;
4018             this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
4019         };
4020 
4021         /**
4022          * set value by integer value
4023          * @name setByInteger
4024          * @memberOf KJUR.asn1.DERInteger
4025          * @function
4026          * @param {Integer} integer value to set
4027          */
4028         this.setByInteger = function(intValue) {
4029             var bi = new BigInteger(String(intValue), 10);
4030             this.setByBigInteger(bi);
4031         };
4032 
4033         /**
4034          * set value by integer value
4035          * @name setValueHex
4036          * @memberOf KJUR.asn1.DERInteger#
4037          * @function
4038          * @param {String} hexadecimal string of integer value
4039          * @description
4040          * <br/>
4041          * NOTE: Value shall be represented by minimum octet length of
4042          * two's complement representation.
4043          * @example
4044          * new KJUR.asn1.DERInteger(123);
4045          * new KJUR.asn1.DERInteger({'int': 123});
4046          * new KJUR.asn1.DERInteger({'hex': '1fad'});
4047          */
4048         this.setValueHex = function(newHexString) {
4049             this.hV = newHexString;
4050         };
4051 
4052         this.getFreshValueHex = function() {
4053             return this.hV;
4054         };
4055 
4056         if (typeof params != "undefined") {
4057             if (typeof params['bigint'] != "undefined") {
4058                 this.setByBigInteger(params['bigint']);
4059             } else if (typeof params['int'] != "undefined") {
4060                 this.setByInteger(params['int']);
4061             } else if (typeof params == "number") {
4062                 this.setByInteger(params);
4063             } else if (typeof params['hex'] != "undefined") {
4064                 this.setValueHex(params['hex']);
4065             }
4066         }
4067     };
4068     YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);
4069 
4070 // ********************************************************************
4071     /**
4072      * class for ASN.1 DER encoded BitString primitive
4073      * @name KJUR.asn1.DERBitString
4074      * @class class for ASN.1 DER encoded BitString primitive
4075      * @extends KJUR.asn1.ASN1Object
4076      * @description
4077      * <br/>
4078      * As for argument 'params' for constructor, you can specify one of
4079      * following properties:
4080      * <ul>
4081      * <li>bin - specify binary string (ex. '10111')</li>
4082      * <li>array - specify array of boolean (ex. [true,false,true,true])</li>
4083      * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li>
4084      * <li>obj - specify {@link KJUR.asn1.ASN1Util.newObject}
4085      * argument for "BitString encapsulates" structure.</li>
4086      * </ul>
4087      * NOTE1: 'params' can be omitted.<br/>
4088      * NOTE2: 'obj' parameter have been supported since
4089      * asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).<br/>
4090      * @example
4091      * // default constructor
4092      * o = new KJUR.asn1.DERBitString();
4093      * // initialize with binary string
4094      * o = new KJUR.asn1.DERBitString({bin: "1011"});
4095      * // initialize with boolean array
4096      * o = new KJUR.asn1.DERBitString({array: [true,false,true,true]});
4097      * // initialize with hexadecimal string (04 is unused bits)
4098      * o = new KJUR.asn1.DEROctetString({hex: "04bac0"});
4099      * // initialize with ASN1Util.newObject argument for encapsulated
4100      * o = new KJUR.asn1.DERBitString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
4101      * // above generates a ASN.1 data like this:
4102      * // BIT STRING, encapsulates {
4103      * //   SEQUENCE {
4104      * //     INTEGER 3
4105      * //     PrintableString 'aaa'
4106      * //     }
4107      * //   }
4108      */
4109     KJUR.asn1.DERBitString = function(params) {
4110         if (params !== undefined && typeof params.obj !== "undefined") {
4111             var o = KJUR.asn1.ASN1Util.newObject(params.obj);
4112             params.hex = "00" + o.getEncodedHex();
4113         }
4114         KJUR.asn1.DERBitString.superclass.constructor.call(this);
4115         this.hT = "03";
4116 
4117         /**
4118          * set ASN.1 value(V) by a hexadecimal string including unused bits
4119          * @name setHexValueIncludingUnusedBits
4120          * @memberOf KJUR.asn1.DERBitString#
4121          * @function
4122          * @param {String} newHexStringIncludingUnusedBits
4123          */
4124         this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) {
4125             this.hTLV = null;
4126             this.isModified = true;
4127             this.hV = newHexStringIncludingUnusedBits;
4128         };
4129 
4130         /**
4131          * set ASN.1 value(V) by unused bit and hexadecimal string of value
4132          * @name setUnusedBitsAndHexValue
4133          * @memberOf KJUR.asn1.DERBitString#
4134          * @function
4135          * @param {Integer} unusedBits
4136          * @param {String} hValue
4137          */
4138         this.setUnusedBitsAndHexValue = function(unusedBits, hValue) {
4139             if (unusedBits < 0 || 7 < unusedBits) {
4140                 throw "unused bits shall be from 0 to 7: u = " + unusedBits;
4141             }
4142             var hUnusedBits = "0" + unusedBits;
4143             this.hTLV = null;
4144             this.isModified = true;
4145             this.hV = hUnusedBits + hValue;
4146         };
4147 
4148         /**
4149          * set ASN.1 DER BitString by binary string<br/>
4150          * @name setByBinaryString
4151          * @memberOf KJUR.asn1.DERBitString#
4152          * @function
4153          * @param {String} binaryString binary value string (i.e. '10111')
4154          * @description
4155          * Its unused bits will be calculated automatically by length of
4156          * 'binaryValue'. <br/>
4157          * NOTE: Trailing zeros '0' will be ignored.
4158          * @example
4159          * o = new KJUR.asn1.DERBitString();
4160          * o.setByBooleanArray("01011");
4161          */
4162         this.setByBinaryString = function(binaryString) {
4163             binaryString = binaryString.replace(/0+$/, '');
4164             var unusedBits = 8 - binaryString.length % 8;
4165             if (unusedBits == 8) unusedBits = 0;
4166             for (var i = 0; i <= unusedBits; i++) {
4167                 binaryString += '0';
4168             }
4169             var h = '';
4170             for (var i = 0; i < binaryString.length - 1; i += 8) {
4171                 var b = binaryString.substr(i, 8);
4172                 var x = parseInt(b, 2).toString(16);
4173                 if (x.length == 1) x = '0' + x;
4174                 h += x;
4175             }
4176             this.hTLV = null;
4177             this.isModified = true;
4178             this.hV = '0' + unusedBits + h;
4179         };
4180 
4181         /**
4182          * set ASN.1 TLV value(V) by an array of boolean<br/>
4183          * @name setByBooleanArray
4184          * @memberOf KJUR.asn1.DERBitString#
4185          * @function
4186          * @param {array} booleanArray array of boolean (ex. [true, false, true])
4187          * @description
4188          * NOTE: Trailing falses will be ignored in the ASN.1 DER Object.
4189          * @example
4190          * o = new KJUR.asn1.DERBitString();
4191          * o.setByBooleanArray([false, true, false, true, true]);
4192          */
4193         this.setByBooleanArray = function(booleanArray) {
4194             var s = '';
4195             for (var i = 0; i < booleanArray.length; i++) {
4196                 if (booleanArray[i] == true) {
4197                     s += '1';
4198                 } else {
4199                     s += '0';
4200                 }
4201             }
4202             this.setByBinaryString(s);
4203         };
4204 
4205         /**
4206          * generate an array of falses with specified length<br/>
4207          * @name newFalseArray
4208          * @memberOf KJUR.asn1.DERBitString
4209          * @function
4210          * @param {Integer} nLength length of array to generate
4211          * @return {array} array of boolean falses
4212          * @description
4213          * This static method may be useful to initialize boolean array.
4214          * @example
4215          * o = new KJUR.asn1.DERBitString();
4216          * o.newFalseArray(3) &rarr; [false, false, false]
4217          */
4218         this.newFalseArray = function(nLength) {
4219             var a = new Array(nLength);
4220             for (var i = 0; i < nLength; i++) {
4221                 a[i] = false;
4222             }
4223             return a;
4224         };
4225 
4226         this.getFreshValueHex = function() {
4227             return this.hV;
4228         };
4229 
4230         if (typeof params != "undefined") {
4231             if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) {
4232                 this.setHexValueIncludingUnusedBits(params);
4233             } else if (typeof params['hex'] != "undefined") {
4234                 this.setHexValueIncludingUnusedBits(params['hex']);
4235             } else if (typeof params['bin'] != "undefined") {
4236                 this.setByBinaryString(params['bin']);
4237             } else if (typeof params['array'] != "undefined") {
4238                 this.setByBooleanArray(params['array']);
4239             }
4240         }
4241     };
4242     YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);
4243 
4244 // ********************************************************************
4245     /**
4246      * class for ASN.1 DER OctetString<br/>
4247      * @name KJUR.asn1.DEROctetString
4248      * @class class for ASN.1 DER OctetString
4249      * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
4250      * @extends KJUR.asn1.DERAbstractString
4251      * @description
4252      * This class provides ASN.1 OctetString simple type.<br/>
4253      * Supported "params" attributes are:
4254      * <ul>
4255      * <li>str - to set a string as a value</li>
4256      * <li>hex - to set a hexadecimal string as a value</li>
4257      * <li>obj - to set a encapsulated ASN.1 value by JSON object
4258      * which is defined in {@link KJUR.asn1.ASN1Util.newObject}</li>
4259      * </ul>
4260      * NOTE: A parameter 'obj' have been supported
4261      * for "OCTET STRING, encapsulates" structure.
4262      * since asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).
4263      * @see KJUR.asn1.DERAbstractString - superclass
4264      * @example
4265      * // default constructor
4266      * o = new KJUR.asn1.DEROctetString();
4267      * // initialize with string
4268      * o = new KJUR.asn1.DEROctetString({str: "aaa"});
4269      * // initialize with hexadecimal string
4270      * o = new KJUR.asn1.DEROctetString({hex: "616161"});
4271      * // initialize with ASN1Util.newObject argument
4272      * o = new KJUR.asn1.DEROctetString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
4273      * // above generates a ASN.1 data like this:
4274      * // OCTET STRING, encapsulates {
4275      * //   SEQUENCE {
4276      * //     INTEGER 3
4277      * //     PrintableString 'aaa'
4278      * //     }
4279      * //   }
4280      */
4281     KJUR.asn1.DEROctetString = function(params) {
4282         if (params !== undefined && typeof params.obj !== "undefined") {
4283             var o = KJUR.asn1.ASN1Util.newObject(params.obj);
4284             params.hex = o.getEncodedHex();
4285         }
4286         KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);
4287         this.hT = "04";
4288     };
4289     YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);
4290 
4291 // ********************************************************************
4292     /**
4293      * class for ASN.1 DER Null
4294      * @name KJUR.asn1.DERNull
4295      * @class class for ASN.1 DER Null
4296      * @extends KJUR.asn1.ASN1Object
4297      * @description
4298      * @see KJUR.asn1.ASN1Object - superclass
4299      */
4300     KJUR.asn1.DERNull = function() {
4301         KJUR.asn1.DERNull.superclass.constructor.call(this);
4302         this.hT = "05";
4303         this.hTLV = "0500";
4304     };
4305     YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);
4306 
4307 // ********************************************************************
4308     /**
4309      * class for ASN.1 DER ObjectIdentifier
4310      * @name KJUR.asn1.DERObjectIdentifier
4311      * @class class for ASN.1 DER ObjectIdentifier
4312      * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'})
4313      * @extends KJUR.asn1.ASN1Object
4314      * @description
4315      * <br/>
4316      * As for argument 'params' for constructor, you can specify one of
4317      * following properties:
4318      * <ul>
4319      * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li>
4320      * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
4321      * </ul>
4322      * NOTE: 'params' can be omitted.
4323      */
4324     KJUR.asn1.DERObjectIdentifier = function(params) {
4325         var itox = function(i) {
4326             var h = i.toString(16);
4327             if (h.length == 1) h = '0' + h;
4328             return h;
4329         };
4330         var roidtox = function(roid) {
4331             var h = '';
4332             var bi = new BigInteger(roid, 10);
4333             var b = bi.toString(2);
4334             var padLen = 7 - b.length % 7;
4335             if (padLen == 7) padLen = 0;
4336             var bPad = '';
4337             for (var i = 0; i < padLen; i++) bPad += '0';
4338             b = bPad + b;
4339             for (var i = 0; i < b.length - 1; i += 7) {
4340                 var b8 = b.substr(i, 7);
4341                 if (i != b.length - 7) b8 = '1' + b8;
4342                 h += itox(parseInt(b8, 2));
4343             }
4344             return h;
4345         };
4346 
4347         KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);
4348         this.hT = "06";
4349 
4350         /**
4351          * set value by a hexadecimal string
4352          * @name setValueHex
4353          * @memberOf KJUR.asn1.DERObjectIdentifier#
4354          * @function
4355          * @param {String} newHexString hexadecimal value of OID bytes
4356          */
4357         this.setValueHex = function(newHexString) {
4358             this.hTLV = null;
4359             this.isModified = true;
4360             this.s = null;
4361             this.hV = newHexString;
4362         };
4363 
4364         /**
4365          * set value by a OID string<br/>
4366          * @name setValueOidString
4367          * @memberOf KJUR.asn1.DERObjectIdentifier#
4368          * @function
4369          * @param {String} oidString OID string (ex. 2.5.4.13)
4370          * @example
4371          * o = new KJUR.asn1.DERObjectIdentifier();
4372          * o.setValueOidString("2.5.4.13");
4373          */
4374         this.setValueOidString = function(oidString) {
4375             if (! oidString.match(/^[0-9.]+$/)) {
4376                 throw "malformed oid string: " + oidString;
4377             }
4378             var h = '';
4379             var a = oidString.split('.');
4380             var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
4381             h += itox(i0);
4382             a.splice(0, 2);
4383             for (var i = 0; i < a.length; i++) {
4384                 h += roidtox(a[i]);
4385             }
4386             this.hTLV = null;
4387             this.isModified = true;
4388             this.s = null;
4389             this.hV = h;
4390         };
4391 
4392         /**
4393          * set value by a OID name
4394          * @name setValueName
4395          * @memberOf KJUR.asn1.DERObjectIdentifier#
4396          * @function
4397          * @param {String} oidName OID name (ex. 'serverAuth')
4398          * @since 1.0.1
4399          * @description
4400          * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'.
4401          * Otherwise raise error.
4402          * @example
4403          * o = new KJUR.asn1.DERObjectIdentifier();
4404          * o.setValueName("serverAuth");
4405          */
4406         this.setValueName = function(oidName) {
4407             var oid = KJUR.asn1.x509.OID.name2oid(oidName);
4408             if (oid !== '') {
4409                 this.setValueOidString(oid);
4410             } else {
4411                 throw "DERObjectIdentifier oidName undefined: " + oidName;
4412             }
4413         };
4414 
4415         this.getFreshValueHex = function() {
4416             return this.hV;
4417         };
4418 
4419         if (params !== undefined) {
4420             if (typeof params === "string") {
4421                 if (params.match(/^[0-2].[0-9.]+$/)) {
4422                     this.setValueOidString(params);
4423                 } else {
4424                     this.setValueName(params);
4425                 }
4426             } else if (params.oid !== undefined) {
4427                 this.setValueOidString(params.oid);
4428             } else if (params.hex !== undefined) {
4429                 this.setValueHex(params.hex);
4430             } else if (params.name !== undefined) {
4431                 this.setValueName(params.name);
4432             }
4433         }
4434     };
4435     YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);
4436 
4437 // ********************************************************************
4438     /**
4439      * class for ASN.1 DER Enumerated
4440      * @name KJUR.asn1.DEREnumerated
4441      * @class class for ASN.1 DER Enumerated
4442      * @extends KJUR.asn1.ASN1Object
4443      * @description
4444      * <br/>
4445      * As for argument 'params' for constructor, you can specify one of
4446      * following properties:
4447      * <ul>
4448      * <li>int - specify initial ASN.1 value(V) by integer value</li>
4449      * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
4450      * </ul>
4451      * NOTE: 'params' can be omitted.
4452      * @example
4453      * new KJUR.asn1.DEREnumerated(123);
4454      * new KJUR.asn1.DEREnumerated({int: 123});
4455      * new KJUR.asn1.DEREnumerated({hex: '1fad'});
4456      */
4457     KJUR.asn1.DEREnumerated = function(params) {
4458         KJUR.asn1.DEREnumerated.superclass.constructor.call(this);
4459         this.hT = "0a";
4460 
4461         /**
4462          * set value by Tom Wu's BigInteger object
4463          * @name setByBigInteger
4464          * @memberOf KJUR.asn1.DEREnumerated#
4465          * @function
4466          * @param {BigInteger} bigIntegerValue to set
4467          */
4468         this.setByBigInteger = function(bigIntegerValue) {
4469             this.hTLV = null;
4470             this.isModified = true;
4471             this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
4472         };
4473 
4474         /**
4475          * set value by integer value
4476          * @name setByInteger
4477          * @memberOf KJUR.asn1.DEREnumerated#
4478          * @function
4479          * @param {Integer} integer value to set
4480          */
4481         this.setByInteger = function(intValue) {
4482             var bi = new BigInteger(String(intValue), 10);
4483             this.setByBigInteger(bi);
4484         };
4485 
4486         /**
4487          * set value by integer value
4488          * @name setValueHex
4489          * @memberOf KJUR.asn1.DEREnumerated#
4490          * @function
4491          * @param {String} hexadecimal string of integer value
4492          * @description
4493          * <br/>
4494          * NOTE: Value shall be represented by minimum octet length of
4495          * two's complement representation.
4496          */
4497         this.setValueHex = function(newHexString) {
4498             this.hV = newHexString;
4499         };
4500 
4501         this.getFreshValueHex = function() {
4502             return this.hV;
4503         };
4504 
4505         if (typeof params != "undefined") {
4506             if (typeof params['int'] != "undefined") {
4507                 this.setByInteger(params['int']);
4508             } else if (typeof params == "number") {
4509                 this.setByInteger(params);
4510             } else if (typeof params['hex'] != "undefined") {
4511                 this.setValueHex(params['hex']);
4512             }
4513         }
4514     };
4515     YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);
4516 
4517 // ********************************************************************
4518     /**
4519      * class for ASN.1 DER UTF8String
4520      * @name KJUR.asn1.DERUTF8String
4521      * @class class for ASN.1 DER UTF8String
4522      * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
4523      * @extends KJUR.asn1.DERAbstractString
4524      * @description
4525      * @see KJUR.asn1.DERAbstractString - superclass
4526      */
4527     KJUR.asn1.DERUTF8String = function(params) {
4528         KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);
4529         this.hT = "0c";
4530     };
4531     YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);
4532 
4533 // ********************************************************************
4534     /**
4535      * class for ASN.1 DER NumericString
4536      * @name KJUR.asn1.DERNumericString
4537      * @class class for ASN.1 DER NumericString
4538      * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
4539      * @extends KJUR.asn1.DERAbstractString
4540      * @description
4541      * @see KJUR.asn1.DERAbstractString - superclass
4542      */
4543     KJUR.asn1.DERNumericString = function(params) {
4544         KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);
4545         this.hT = "12";
4546     };
4547     YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);
4548 
4549 // ********************************************************************
4550     /**
4551      * class for ASN.1 DER PrintableString
4552      * @name KJUR.asn1.DERPrintableString
4553      * @class class for ASN.1 DER PrintableString
4554      * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
4555      * @extends KJUR.asn1.DERAbstractString
4556      * @description
4557      * @see KJUR.asn1.DERAbstractString - superclass
4558      */
4559     KJUR.asn1.DERPrintableString = function(params) {
4560         KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);
4561         this.hT = "13";
4562     };
4563     YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);
4564 
4565 // ********************************************************************
4566     /**
4567      * class for ASN.1 DER TeletexString
4568      * @name KJUR.asn1.DERTeletexString
4569      * @class class for ASN.1 DER TeletexString
4570      * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
4571      * @extends KJUR.asn1.DERAbstractString
4572      * @description
4573      * @see KJUR.asn1.DERAbstractString - superclass
4574      */
4575     KJUR.asn1.DERTeletexString = function(params) {
4576         KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);
4577         this.hT = "14";
4578     };
4579     YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);
4580 
4581 // ********************************************************************
4582     /**
4583      * class for ASN.1 DER IA5String
4584      * @name KJUR.asn1.DERIA5String
4585      * @class class for ASN.1 DER IA5String
4586      * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
4587      * @extends KJUR.asn1.DERAbstractString
4588      * @description
4589      * @see KJUR.asn1.DERAbstractString - superclass
4590      */
4591     KJUR.asn1.DERIA5String = function(params) {
4592         KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);
4593         this.hT = "16";
4594     };
4595     YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);
4596 
4597 // ********************************************************************
4598     /**
4599      * class for ASN.1 DER UTCTime
4600      * @name KJUR.asn1.DERUTCTime
4601      * @class class for ASN.1 DER UTCTime
4602      * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
4603      * @extends KJUR.asn1.DERAbstractTime
4604      * @description
4605      * <br/>
4606      * As for argument 'params' for constructor, you can specify one of
4607      * following properties:
4608      * <ul>
4609      * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li>
4610      * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
4611      * <li>date - specify Date object.</li>
4612      * </ul>
4613      * NOTE: 'params' can be omitted.
4614      * <h4>EXAMPLES</h4>
4615      * @example
4616      * d1 = new KJUR.asn1.DERUTCTime();
4617      * d1.setString('130430125959Z');
4618      *
4619      * d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'});
4620      * d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))});
4621      * d4 = new KJUR.asn1.DERUTCTime('130430125959Z');
4622      */
4623     KJUR.asn1.DERUTCTime = function(params) {
4624         KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);
4625         this.hT = "17";
4626 
4627         /**
4628          * set value by a Date object<br/>
4629          * @name setByDate
4630          * @memberOf KJUR.asn1.DERUTCTime#
4631          * @function
4632          * @param {Date} dateObject Date object to set ASN.1 value(V)
4633          * @example
4634          * o = new KJUR.asn1.DERUTCTime();
4635          * o.setByDate(new Date("2016/12/31"));
4636          */
4637         this.setByDate = function(dateObject) {
4638             this.hTLV = null;
4639             this.isModified = true;
4640             this.date = dateObject;
4641             this.s = this.formatDate(this.date, 'utc');
4642             this.hV = stohex(this.s);
4643         };
4644 
4645         this.getFreshValueHex = function() {
4646             if (typeof this.date == "undefined" && typeof this.s == "undefined") {
4647                 this.date = new Date();
4648                 this.s = this.formatDate(this.date, 'utc');
4649                 this.hV = stohex(this.s);
4650             }
4651             return this.hV;
4652         };
4653 
4654         if (params !== undefined) {
4655             if (params.str !== undefined) {
4656                 this.setString(params.str);
4657             } else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) {
4658                 this.setString(params);
4659             } else if (params.hex !== undefined) {
4660                 this.setStringHex(params.hex);
4661             } else if (params.date !== undefined) {
4662                 this.setByDate(params.date);
4663             }
4664         }
4665     };
4666     YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);
4667 
4668 // ********************************************************************
4669     /**
4670      * class for ASN.1 DER GeneralizedTime
4671      * @name KJUR.asn1.DERGeneralizedTime
4672      * @class class for ASN.1 DER GeneralizedTime
4673      * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'})
4674      * @property {Boolean} withMillis flag to show milliseconds or not
4675      * @extends KJUR.asn1.DERAbstractTime
4676      * @description
4677      * <br/>
4678      * As for argument 'params' for constructor, you can specify one of
4679      * following properties:
4680      * <ul>
4681      * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li>
4682      * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
4683      * <li>date - specify Date object.</li>
4684      * <li>millis - specify flag to show milliseconds (from 1.0.6)</li>
4685      * </ul>
4686      * NOTE1: 'params' can be omitted.
4687      * NOTE2: 'withMillis' property is supported from asn1 1.0.6.
4688      */
4689     KJUR.asn1.DERGeneralizedTime = function(params) {
4690         KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);
4691         this.hT = "18";
4692         this.withMillis = false;
4693 
4694         /**
4695          * set value by a Date object
4696          * @name setByDate
4697          * @memberOf KJUR.asn1.DERGeneralizedTime#
4698          * @function
4699          * @param {Date} dateObject Date object to set ASN.1 value(V)
4700          * @example
4701          * When you specify UTC time, use 'Date.UTC' method like this:<br/>
4702          * o1 = new DERUTCTime();
4703          * o1.setByDate(date);
4704          *
4705          * date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59
4706          */
4707         this.setByDate = function(dateObject) {
4708             this.hTLV = null;
4709             this.isModified = true;
4710             this.date = dateObject;
4711             this.s = this.formatDate(this.date, 'gen', this.withMillis);
4712             this.hV = stohex(this.s);
4713         };
4714 
4715         this.getFreshValueHex = function() {
4716             if (this.date === undefined && this.s === undefined) {
4717                 this.date = new Date();
4718                 this.s = this.formatDate(this.date, 'gen', this.withMillis);
4719                 this.hV = stohex(this.s);
4720             }
4721             return this.hV;
4722         };
4723 
4724         if (params !== undefined) {
4725             if (params.str !== undefined) {
4726                 this.setString(params.str);
4727             } else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) {
4728                 this.setString(params);
4729             } else if (params.hex !== undefined) {
4730                 this.setStringHex(params.hex);
4731             } else if (params.date !== undefined) {
4732                 this.setByDate(params.date);
4733             }
4734             if (params.millis === true) {
4735                 this.withMillis = true;
4736             }
4737         }
4738     };
4739     YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);
4740 
4741 // ********************************************************************
4742     /**
4743      * class for ASN.1 DER Sequence
4744      * @name KJUR.asn1.DERSequence
4745      * @class class for ASN.1 DER Sequence
4746      * @extends KJUR.asn1.DERAbstractStructured
4747      * @description
4748      * <br/>
4749      * As for argument 'params' for constructor, you can specify one of
4750      * following properties:
4751      * <ul>
4752      * <li>array - specify array of ASN1Object to set elements of content</li>
4753      * </ul>
4754      * NOTE: 'params' can be omitted.
4755      */
4756     KJUR.asn1.DERSequence = function(params) {
4757         KJUR.asn1.DERSequence.superclass.constructor.call(this, params);
4758         this.hT = "30";
4759         this.getFreshValueHex = function() {
4760             var h = '';
4761             for (var i = 0; i < this.asn1Array.length; i++) {
4762                 var asn1Obj = this.asn1Array[i];
4763                 h += asn1Obj.getEncodedHex();
4764             }
4765             this.hV = h;
4766             return this.hV;
4767         };
4768     };
4769     YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);
4770 
4771 // ********************************************************************
4772     /**
4773      * class for ASN.1 DER Set
4774      * @name KJUR.asn1.DERSet
4775      * @class class for ASN.1 DER Set
4776      * @extends KJUR.asn1.DERAbstractStructured
4777      * @description
4778      * <br/>
4779      * As for argument 'params' for constructor, you can specify one of
4780      * following properties:
4781      * <ul>
4782      * <li>array - specify array of ASN1Object to set elements of content</li>
4783      * <li>sortflag - flag for sort (default: true). ASN.1 BER is not sorted in 'SET OF'.</li>
4784      * </ul>
4785      * NOTE1: 'params' can be omitted.<br/>
4786      * NOTE2: sortflag is supported since 1.0.5.
4787      */
4788     KJUR.asn1.DERSet = function(params) {
4789         KJUR.asn1.DERSet.superclass.constructor.call(this, params);
4790         this.hT = "31";
4791         this.sortFlag = true; // item shall be sorted only in ASN.1 DER
4792         this.getFreshValueHex = function() {
4793             var a = new Array();
4794             for (var i = 0; i < this.asn1Array.length; i++) {
4795                 var asn1Obj = this.asn1Array[i];
4796                 a.push(asn1Obj.getEncodedHex());
4797             }
4798             if (this.sortFlag == true) a.sort();
4799             this.hV = a.join('');
4800             return this.hV;
4801         };
4802 
4803         if (typeof params != "undefined") {
4804             if (typeof params.sortflag != "undefined" &&
4805                 params.sortflag == false)
4806                 this.sortFlag = false;
4807         }
4808     };
4809     YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);
4810 
4811 // ********************************************************************
4812     /**
4813      * class for ASN.1 DER TaggedObject
4814      * @name KJUR.asn1.DERTaggedObject
4815      * @class class for ASN.1 DER TaggedObject
4816      * @extends KJUR.asn1.ASN1Object
4817      * @description
4818      * <br/>
4819      * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object.
4820      * For example, if you find '[1]' tag in a ASN.1 dump,
4821      * 'tagNoHex' will be 'a1'.
4822      * <br/>
4823      * As for optional argument 'params' for constructor, you can specify *ANY* of
4824      * following properties:
4825      * <ul>
4826      * <li>explicit - specify true if this is explicit tag otherwise false
4827      *     (default is 'true').</li>
4828      * <li>tag - specify tag (default is 'a0' which means [0])</li>
4829      * <li>obj - specify ASN1Object which is tagged</li>
4830      * </ul>
4831      * @example
4832      * d1 = new KJUR.asn1.DERUTF8String({'str':'a'});
4833      * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1});
4834      * hex = d2.getEncodedHex();
4835      */
4836     KJUR.asn1.DERTaggedObject = function(params) {
4837         KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);
4838         this.hT = "a0";
4839         this.hV = '';
4840         this.isExplicit = true;
4841         this.asn1Object = null;
4842 
4843         /**
4844          * set value by an ASN1Object
4845          * @name setString
4846          * @memberOf KJUR.asn1.DERTaggedObject#
4847          * @function
4848          * @param {Boolean} isExplicitFlag flag for explicit/implicit tag
4849          * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag
4850          * @param {ASN1Object} asn1Object ASN.1 to encapsulate
4851          */
4852         this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) {
4853             this.hT = tagNoHex;
4854             this.isExplicit = isExplicitFlag;
4855             this.asn1Object = asn1Object;
4856             if (this.isExplicit) {
4857                 this.hV = this.asn1Object.getEncodedHex();
4858                 this.hTLV = null;
4859                 this.isModified = true;
4860             } else {
4861                 this.hV = null;
4862                 this.hTLV = asn1Object.getEncodedHex();
4863                 this.hTLV = this.hTLV.replace(/^../, tagNoHex);
4864                 this.isModified = false;
4865             }
4866         };
4867 
4868         this.getFreshValueHex = function() {
4869             return this.hV;
4870         };
4871 
4872         if (typeof params != "undefined") {
4873             if (typeof params['tag'] != "undefined") {
4874                 this.hT = params['tag'];
4875             }
4876             if (typeof params['explicit'] != "undefined") {
4877                 this.isExplicit = params['explicit'];
4878             }
4879             if (typeof params['obj'] != "undefined") {
4880                 this.asn1Object = params['obj'];
4881                 this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);
4882             }
4883         }
4884     };
4885     YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);
4886 
4887     /**
4888      * Create a new JSEncryptRSAKey that extends Tom Wu's RSA key object.
4889      * This object is just a decorator for parsing the key parameter
4890      * @param {string|Object} key - The key in string format, or an object containing
4891      * the parameters needed to build a RSAKey object.
4892      * @constructor
4893      */
4894     var JSEncryptRSAKey = /** @class */ (function (_super) {
4895         __extends(JSEncryptRSAKey, _super);
4896         function JSEncryptRSAKey(key) {
4897             var _this = _super.call(this) || this;
4898             // Call the super constructor.
4899             //  RSAKey.call(this);
4900             // If a key key was provided.
4901             if (key) {
4902                 // If this is a string...
4903                 if (typeof key === "string") {
4904                     _this.parseKey(key);
4905                 }
4906                 else if (JSEncryptRSAKey.hasPrivateKeyProperty(key) ||
4907                     JSEncryptRSAKey.hasPublicKeyProperty(key)) {
4908                     // Set the values for the key.
4909                     _this.parsePropertiesFrom(key);
4910                 }
4911             }
4912             return _this;
4913         }
4914         /**
4915          * Method to parse a pem encoded string containing both a public or private key.
4916          * The method will translate the pem encoded string in a der encoded string and
4917          * will parse private key and public key parameters. This method accepts public key
4918          * in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1).
4919          *
4920          * @todo Check how many rsa formats use the same format of pkcs #1.
4921          *
4922          * The format is defined as:
4923          * PublicKeyInfo ::= SEQUENCE {
4924          *   algorithm       AlgorithmIdentifier,
4925          *   PublicKey       BIT STRING
4926          * }
4927          * Where AlgorithmIdentifier is:
4928          * AlgorithmIdentifier ::= SEQUENCE {
4929          *   algorithm       OBJECT IDENTIFIER,     the OID of the enc algorithm
4930          *   parameters      ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
4931          * }
4932          * and PublicKey is a SEQUENCE encapsulated in a BIT STRING
4933          * RSAPublicKey ::= SEQUENCE {
4934          *   modulus           INTEGER,  -- n
4935          *   publicExponent    INTEGER   -- e
4936          * }
4937          * it's possible to examine the structure of the keys obtained from openssl using
4938          * an asn.1 dumper as the one used here to parse the components: http://lapo.it/asn1js/
4939          * @argument {string} pem the pem encoded string, can include the BEGIN/END header/footer
4940          * @private
4941          */
4942         JSEncryptRSAKey.prototype.parseKey = function (pem) {
4943             try {
4944                 var modulus = 0;
4945                 var public_exponent = 0;
4946                 var reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/;
4947                 var der = reHex.test(pem) ? Hex.decode(pem) : Base64.unarmor(pem);
4948                 var asn1 = ASN1.decode(der);
4949                 // Fixes a bug with OpenSSL 1.0+ private keys
4950                 if (asn1.sub.length === 3) {
4951                     asn1 = asn1.sub[2].sub[0];
4952                 }
4953                 if (asn1.sub.length === 9) {
4954                     // Parse the private key.
4955                     modulus = asn1.sub[1].getHexStringValue(); // bigint
4956                     this.n = parseBigInt(modulus, 16);
4957                     public_exponent = asn1.sub[2].getHexStringValue(); // int
4958                     this.e = parseInt(public_exponent, 16);
4959                     var private_exponent = asn1.sub[3].getHexStringValue(); // bigint
4960                     this.d = parseBigInt(private_exponent, 16);
4961                     var prime1 = asn1.sub[4].getHexStringValue(); // bigint
4962                     this.p = parseBigInt(prime1, 16);
4963                     var prime2 = asn1.sub[5].getHexStringValue(); // bigint
4964                     this.q = parseBigInt(prime2, 16);
4965                     var exponent1 = asn1.sub[6].getHexStringValue(); // bigint
4966                     this.dmp1 = parseBigInt(exponent1, 16);
4967                     var exponent2 = asn1.sub[7].getHexStringValue(); // bigint
4968                     this.dmq1 = parseBigInt(exponent2, 16);
4969                     var coefficient = asn1.sub[8].getHexStringValue(); // bigint
4970                     this.coeff = parseBigInt(coefficient, 16);
4971                 }
4972                 else if (asn1.sub.length === 2) {
4973                     // Parse the public key.
4974                     var bit_string = asn1.sub[1];
4975                     var sequence = bit_string.sub[0];
4976                     modulus = sequence.sub[0].getHexStringValue();
4977                     this.n = parseBigInt(modulus, 16);
4978                     public_exponent = sequence.sub[1].getHexStringValue();
4979                     this.e = parseInt(public_exponent, 16);
4980                 }
4981                 else {
4982                     return false;
4983                 }
4984                 return true;
4985             }
4986             catch (ex) {
4987                 return false;
4988             }
4989         };
4990         /**
4991          * Translate rsa parameters in a hex encoded string representing the rsa key.
4992          *
4993          * The translation follow the ASN.1 notation :
4994          * RSAPrivateKey ::= SEQUENCE {
4995          *   version           Version,
4996          *   modulus           INTEGER,  -- n
4997          *   publicExponent    INTEGER,  -- e
4998          *   privateExponent   INTEGER,  -- d
4999          *   prime1            INTEGER,  -- p
5000          *   prime2            INTEGER,  -- q
5001          *   exponent1         INTEGER,  -- d mod (p1)
5002          *   exponent2         INTEGER,  -- d mod (q-1)
5003          *   coefficient       INTEGER,  -- (inverse of q) mod p
5004          * }
5005          * @returns {string}  DER Encoded String representing the rsa private key
5006          * @private
5007          */
5008         JSEncryptRSAKey.prototype.getPrivateBaseKey = function () {
5009             var options = {
5010                 array: [
5011                     new KJUR.asn1.DERInteger({ int: 0 }),
5012                     new KJUR.asn1.DERInteger({ bigint: this.n }),
5013                     new KJUR.asn1.DERInteger({ int: this.e }),
5014                     new KJUR.asn1.DERInteger({ bigint: this.d }),
5015                     new KJUR.asn1.DERInteger({ bigint: this.p }),
5016                     new KJUR.asn1.DERInteger({ bigint: this.q }),
5017                     new KJUR.asn1.DERInteger({ bigint: this.dmp1 }),
5018                     new KJUR.asn1.DERInteger({ bigint: this.dmq1 }),
5019                     new KJUR.asn1.DERInteger({ bigint: this.coeff })
5020                 ]
5021             };
5022             var seq = new KJUR.asn1.DERSequence(options);
5023             return seq.getEncodedHex();
5024         };
5025         /**
5026          * base64 (pem) encoded version of the DER encoded representation
5027          * @returns {string} pem encoded representation without header and footer
5028          * @public
5029          */
5030         JSEncryptRSAKey.prototype.getPrivateBaseKeyB64 = function () {
5031             return hex2b64(this.getPrivateBaseKey());
5032         };
5033         /**
5034          * Translate rsa parameters in a hex encoded string representing the rsa public key.
5035          * The representation follow the ASN.1 notation :
5036          * PublicKeyInfo ::= SEQUENCE {
5037          *   algorithm       AlgorithmIdentifier,
5038          *   PublicKey       BIT STRING
5039          * }
5040          * Where AlgorithmIdentifier is:
5041          * AlgorithmIdentifier ::= SEQUENCE {
5042          *   algorithm       OBJECT IDENTIFIER,     the OID of the enc algorithm
5043          *   parameters      ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
5044          * }
5045          * and PublicKey is a SEQUENCE encapsulated in a BIT STRING
5046          * RSAPublicKey ::= SEQUENCE {
5047          *   modulus           INTEGER,  -- n
5048          *   publicExponent    INTEGER   -- e
5049          * }
5050          * @returns {string} DER Encoded String representing the rsa public key
5051          * @private
5052          */
5053         JSEncryptRSAKey.prototype.getPublicBaseKey = function () {
5054             var first_sequence = new KJUR.asn1.DERSequence({
5055                 array: [
5056                     new KJUR.asn1.DERObjectIdentifier({ oid: "1.2.840.113549.1.1.1" }),
5057                     new KJUR.asn1.DERNull()
5058                 ]
5059             });
5060             var second_sequence = new KJUR.asn1.DERSequence({
5061                 array: [
5062                     new KJUR.asn1.DERInteger({ bigint: this.n }),
5063                     new KJUR.asn1.DERInteger({ int: this.e })
5064                 ]
5065             });
5066             var bit_string = new KJUR.asn1.DERBitString({
5067                 hex: "00" + second_sequence.getEncodedHex()
5068             });
5069             var seq = new KJUR.asn1.DERSequence({
5070                 array: [
5071                     first_sequence,
5072                     bit_string
5073                 ]
5074             });
5075             return seq.getEncodedHex();
5076         };
5077         /**
5078          * base64 (pem) encoded version of the DER encoded representation
5079          * @returns {string} pem encoded representation without header and footer
5080          * @public
5081          */
5082         JSEncryptRSAKey.prototype.getPublicBaseKeyB64 = function () {
5083             return hex2b64(this.getPublicBaseKey());
5084         };
5085         /**
5086          * wrap the string in block of width chars. The default value for rsa keys is 64
5087          * characters.
5088          * @param {string} str the pem encoded string without header and footer
5089          * @param {Number} [width=64] - the length the string has to be wrapped at
5090          * @returns {string}
5091          * @private
5092          */
5093         JSEncryptRSAKey.wordwrap = function (str, width) {
5094             width = width || 64;
5095             if (!str) {
5096                 return str;
5097             }
5098             var regex = "(.{1," + width + "})( +|$\n?)|(.{1," + width + "})";
5099             return str.match(RegExp(regex, "g")).join("\n");
5100         };
5101         /**
5102          * Retrieve the pem encoded private key
5103          * @returns {string} the pem encoded private key with header/footer
5104          * @public
5105          */
5106         JSEncryptRSAKey.prototype.getPrivateKey = function () {
5107             var key = "-----BEGIN RSA PRIVATE KEY-----\n";
5108             key += JSEncryptRSAKey.wordwrap(this.getPrivateBaseKeyB64()) + "\n";
5109             key += "-----END RSA PRIVATE KEY-----";
5110             return key;
5111         };
5112         /**
5113          * Retrieve the pem encoded public key
5114          * @returns {string} the pem encoded public key with header/footer
5115          * @public
5116          */
5117         JSEncryptRSAKey.prototype.getPublicKey = function () {
5118             var key = "-----BEGIN PUBLIC KEY-----\n";
5119             key += JSEncryptRSAKey.wordwrap(this.getPublicBaseKeyB64()) + "\n";
5120             key += "-----END PUBLIC KEY-----";
5121             return key;
5122         };
5123         /**
5124          * Check if the object contains the necessary parameters to populate the rsa modulus
5125          * and public exponent parameters.
5126          * @param {Object} [obj={}] - An object that may contain the two public key
5127          * parameters
5128          * @returns {boolean} true if the object contains both the modulus and the public exponent
5129          * properties (n and e)
5130          * @todo check for types of n and e. N should be a parseable bigInt object, E should
5131          * be a parseable integer number
5132          * @private
5133          */
5134         JSEncryptRSAKey.hasPublicKeyProperty = function (obj) {
5135             obj = obj || {};
5136             return (obj.hasOwnProperty("n") &&
5137                 obj.hasOwnProperty("e"));
5138         };
5139         /**
5140          * Check if the object contains ALL the parameters of an RSA key.
5141          * @param {Object} [obj={}] - An object that may contain nine rsa key
5142          * parameters
5143          * @returns {boolean} true if the object contains all the parameters needed
5144          * @todo check for types of the parameters all the parameters but the public exponent
5145          * should be parseable bigint objects, the public exponent should be a parseable integer number
5146          * @private
5147          */
5148         JSEncryptRSAKey.hasPrivateKeyProperty = function (obj) {
5149             obj = obj || {};
5150             return (obj.hasOwnProperty("n") &&
5151                 obj.hasOwnProperty("e") &&
5152                 obj.hasOwnProperty("d") &&
5153                 obj.hasOwnProperty("p") &&
5154                 obj.hasOwnProperty("q") &&
5155                 obj.hasOwnProperty("dmp1") &&
5156                 obj.hasOwnProperty("dmq1") &&
5157                 obj.hasOwnProperty("coeff"));
5158         };
5159         /**
5160          * Parse the properties of obj in the current rsa object. Obj should AT LEAST
5161          * include the modulus and public exponent (n, e) parameters.
5162          * @param {Object} obj - the object containing rsa parameters
5163          * @private
5164          */
5165         JSEncryptRSAKey.prototype.parsePropertiesFrom = function (obj) {
5166             this.n = obj.n;
5167             this.e = obj.e;
5168             if (obj.hasOwnProperty("d")) {
5169                 this.d = obj.d;
5170                 this.p = obj.p;
5171                 this.q = obj.q;
5172                 this.dmp1 = obj.dmp1;
5173                 this.dmq1 = obj.dmq1;
5174                 this.coeff = obj.coeff;
5175             }
5176         };
5177         return JSEncryptRSAKey;
5178     }(RSAKey));
5179 
5180     /**
5181      *
5182      * @param {Object} [options = {}] - An object to customize JSEncrypt behaviour
5183      * possible parameters are:
5184      * - default_key_size        {number}  default: 1024 the key size in bit
5185      * - default_public_exponent {string}  default: '010001' the hexadecimal representation of the public exponent
5186      * - log                     {boolean} default: false whether log warn/error or not
5187      * @constructor
5188      */
5189     var JSEncrypt = /** @class */ (function () {
5190         function JSEncrypt(options) {
5191             options = options || {};
5192             this.default_key_size = parseInt(options.default_key_size, 10) || 1024;
5193             this.default_public_exponent = options.default_public_exponent || "010001"; // 65537 default openssl public exponent for rsa key type
5194             this.log = options.log || false;
5195             // The private and public key.
5196             this.key = null;
5197         }
5198         /**
5199          * Method to set the rsa key parameter (one method is enough to set both the public
5200          * and the private key, since the private key contains the public key paramenters)
5201          * Log a warning if logs are enabled
5202          * @param {Object|string} key the pem encoded string or an object (with or without header/footer)
5203          * @public
5204          */
5205         JSEncrypt.prototype.setKey = function (key) {
5206             if (this.log && this.key) {
5207                 console.warn("A key was already set, overriding existing.");
5208             }
5209             this.key = new JSEncryptRSAKey(key);
5210         };
5211         /**
5212          * Proxy method for setKey, for api compatibility
5213          * @see setKey
5214          * @public
5215          */
5216         JSEncrypt.prototype.setPrivateKey = function (privkey) {
5217             // Create the key.
5218             this.setKey(privkey);
5219         };
5220         /**
5221          * Proxy method for setKey, for api compatibility
5222          * @see setKey
5223          * @public
5224          */
5225         JSEncrypt.prototype.setPublicKey = function (pubkey) {
5226             // Sets the public key.
5227             this.setKey(pubkey);
5228         };
5229         /**
5230          * Proxy method for RSAKey object's decrypt, decrypt the string using the private
5231          * components of the rsa key object. Note that if the object was not set will be created
5232          * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor
5233          * @param {string} str base64 encoded crypted string to decrypt
5234          * @return {string} the decrypted string
5235          * @public
5236          */
5237         JSEncrypt.prototype.decrypt = function (str) {
5238             // Return the decrypted string.
5239             try {
5240                 return this.getKey().decrypt(b64tohex(str));
5241             }
5242             catch (ex) {
5243                 return false;
5244             }
5245         };
5246         /**
5247          * Proxy method for RSAKey object's encrypt, encrypt the string using the public
5248          * components of the rsa key object. Note that if the object was not set will be created
5249          * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor
5250          * @param {string} str the string to encrypt
5251          * @return {string} the encrypted string encoded in base64
5252          * @public
5253          */
5254         JSEncrypt.prototype.encrypt = function (str) {
5255             // Return the encrypted string.
5256             try {
5257                 return hex2b64(this.getKey().encrypt(str));
5258             }
5259             catch (ex) {
5260                 return false;
5261             }
5262         };
5263         /**
5264          * Proxy method for RSAKey object's sign.
5265          * @param {string} str the string to sign
5266          * @param {function} digestMethod hash method
5267          * @param {string} digestName the name of the hash algorithm
5268          * @return {string} the signature encoded in base64
5269          * @public
5270          */
5271         JSEncrypt.prototype.sign = function (str, digestMethod, digestName) {
5272             // return the RSA signature of 'str' in 'hex' format.
5273             try {
5274                 return hex2b64(this.getKey().sign(str, digestMethod, digestName));
5275             }
5276             catch (ex) {
5277                 return false;
5278             }
5279         };
5280         /**
5281          * Proxy method for RSAKey object's verify.
5282          * @param {string} str the string to verify
5283          * @param {string} signature the signature encoded in base64 to compare the string to
5284          * @param {function} digestMethod hash method
5285          * @return {boolean} whether the data and signature match
5286          * @public
5287          */
5288         JSEncrypt.prototype.verify = function (str, signature, digestMethod) {
5289             // Return the decrypted 'digest' of the signature.
5290             try {
5291                 return this.getKey().verify(str, b64tohex(signature), digestMethod);
5292             }
5293             catch (ex) {
5294                 return false;
5295             }
5296         };
5297         /**
5298          * Getter for the current JSEncryptRSAKey object. If it doesn't exists a new object
5299          * will be created and returned
5300          * @param {callback} [cb] the callback to be called if we want the key to be generated
5301          * in an async fashion
5302          * @returns {JSEncryptRSAKey} the JSEncryptRSAKey object
5303          * @public
5304          */
5305         JSEncrypt.prototype.getKey = function (cb) {
5306             // Only create new if it does not exist.
5307             if (!this.key) {
5308                 // Get a new private key.
5309                 this.key = new JSEncryptRSAKey();
5310                 if (cb && {}.toString.call(cb) === "[object Function]") {
5311                     this.key.generateAsync(this.default_key_size, this.default_public_exponent, cb);
5312                     return;
5313                 }
5314                 // Generate the key.
5315                 this.key.generate(this.default_key_size, this.default_public_exponent);
5316             }
5317             return this.key;
5318         };
5319         /**
5320          * Returns the pem encoded representation of the private key
5321          * If the key doesn't exists a new key will be created
5322          * @returns {string} pem encoded representation of the private key WITH header and footer
5323          * @public
5324          */
5325         JSEncrypt.prototype.getPrivateKey = function () {
5326             // Return the private representation of this key.
5327             return this.getKey().getPrivateKey();
5328         };
5329         /**
5330          * Returns the pem encoded representation of the private key
5331          * If the key doesn't exists a new key will be created
5332          * @returns {string} pem encoded representation of the private key WITHOUT header and footer
5333          * @public
5334          */
5335         JSEncrypt.prototype.getPrivateKeyB64 = function () {
5336             // Return the private representation of this key.
5337             return this.getKey().getPrivateBaseKeyB64();
5338         };
5339         /**
5340          * Returns the pem encoded representation of the public key
5341          * If the key doesn't exists a new key will be created
5342          * @returns {string} pem encoded representation of the public key WITH header and footer
5343          * @public
5344          */
5345         JSEncrypt.prototype.getPublicKey = function () {
5346             // Return the private representation of this key.
5347             return this.getKey().getPublicKey();
5348         };
5349         /**
5350          * Returns the pem encoded representation of the public key
5351          * If the key doesn't exists a new key will be created
5352          * @returns {string} pem encoded representation of the public key WITHOUT header and footer
5353          * @public
5354          */
5355         JSEncrypt.prototype.getPublicKeyB64 = function () {
5356             // Return the private representation of this key.
5357             return this.getKey().getPublicBaseKeyB64();
5358         };
5359         JSEncrypt.version = "3.0.0-rc.1";
5360         return JSEncrypt;
5361     }());
5362 
5363     window.JSEncrypt = JSEncrypt;
5364 
5365     exports.JSEncrypt = JSEncrypt;
5366     exports.default = JSEncrypt;
5367 
5368     Object.defineProperty(exports, '__esModule', { value: true });
5369 
5370 })));
View Code

输出如下:

public encrypted:  T2LFtY3dF_b6OBO07BN-3LtMSEBZqDukovDZ4HGCff8wosvlowf6IFJ3U7LFBIeHfiHBKiFuAV8-pFltCfTXtA4AwgVUnwbBMBWBfIJiLDi02ev30V-5BcYEuSF-cEdnSUd7WecrX4rHhzYLueGuj8H6c7RRbSbrJ6_3EFfU-K0
private uncrypted:  i like JS
private uncrypted:  i like php
private uncrypted:  i like java

 

VUE版本:

import JSEncrypt from 'jsencrypt';
import CryptoJS from 'crypto-js';

const encryptor = new JSEncrypt()  // 创建加密对象实例
//之前ssl生成的公钥,复制的时候要小心不要有空格
let pubKey = '-----BEGIN PUBLIC KEY-----\n' +
  'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDajaSeq9ugCgh95ObVG4KK/AT0\n' +
  'O8t4YbkPu5SZZSfQN/2O7iQBsDqZwkSpu/hQ733wRTyTN1rjrmjdzFfSMRLmJ8Wf\n' +
  'TrTQirE/Yf2pE/B3Mz5yVUDJDUy7m6oVZ0sHBV1/do+MRIfSgmKmJLbem/YZeiVY\n' +
  'MHvzAQmF7EU37mtdlwIDAQAB\n' +
  '-----END PUBLIC KEY-----';

encryptor.setPublicKey(pubKey)//设置公钥
//之前ssl生成的秘钥
let priKey  = '-----BEGIN PRIVATE KEY-----\n' +
  'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANqNpJ6r26AKCH3k\n' +
  '5tUbgor8BPQ7y3hhuQ+7lJllJ9A3/Y7uJAGwOpnCRKm7+FDvffBFPJM3WuOuaN3M\n' +
  'V9IxEuYnxZ9OtNCKsT9h/akT8HczPnJVQMkNTLubqhVnSwcFXX92j4xEh9KCYqYk\n' +
  'tt6b9hl6JVgwe/MBCYXsRTfua12XAgMBAAECgYEAyxAoEDVlzoED+tUflIoG9NPM\n' +
  'VpDoMGW76N5E53GRWGltccvaMKdpC0vxODOqOKkMvp3V9oLMNBfs34fpYSavguks\n' +
  'W+C/+TNIghDbXH/iUNzLiwlBEtdVKk+wQsH0PwZZofvZhqiS33qeSPhxhauAwjc6\n' +
  'cBNQdLMonfHN59byaSECQQD2gWJiottcGjGNwpFwtp2pd75/nYdeetKV9kO98W71\n' +
  'ueZ74TIR3cjFRzOQKAAYyyj/dXFL5XadpJbvg2PDhRq9AkEA4vikhmFkNW1gbT1X\n' +
  'Dm/phItkDY16hYBb/oLJw+QO6QrEMRoRvi+C+wTMGck2z/WOWqYM39fixQsG7JA2\n' +
  'dRXI4wJAAUOIjZjoJwC7YE6vEDTfeg7zGxRjrUhT7BDnKAIk332kgN4Ws6C/dsN2\n' +
  'sDaESZxBCY5AlnMGuKgvXer+h/IWwQJAHRhEdtlrMBIaR0aSr04XQB9iLv6Q0yY2\n' +
  'JLT9Sjgk1SjFJ4ow9hE/GBBwXWnWtefDXMlmYxdYgWu9cnu2D2JAgwJBAI4DzrSn\n' +
  '8FQ4xSvtGQJ0XPm7Do+/jpvBX1r0dnDP35PD9HJgG/vyrHw2fMYfKqSCVTEY5nKl\n' +
  'gMqK13pPTVpRSdM=\n' +
  '-----END PRIVATE KEY-----';

encryptor.setPrivateKey(priKey);  //设置秘钥

let encrypted = encryptor.encrypt('123456')  // 对内容进行加密
let signature = encryptor.sign(encrypted, CryptoJS.SHA256,'sha256');

console.log("encrypted", encrypted);
console.log("signature", signature);

let verified = encryptor.verify(encrypted, signature, CryptoJS.SHA256);
console.log("verified", verified);

let uncrypted = encryptor.decrypt(encrypted); //解密之前拿公钥加密的内容
console.log("uncrypted", uncrypted);

 

 

PS:

https://github.com/travist/jsencrypt

https://www.cnblogs.com/Lrn14616/p/10154529.html

https://blog.csdn.net/MrSpirit/article/details/79066537

https://my.oschina.net/gKWW0kOYB/blog/1836342

https://blog.csdn.net/qq_28027903/article/details/73289156

https://www.cnblogs.com/twilight-sam/p/5549121.html

https://www.cnblogs.com/roam/p/5974061.html

https://www.cnblogs.com/jxust-jiege666/p/8733204.html

 

posted @ 2019-01-15 21:16  phpdragon  阅读(5481)  评论(0编辑  收藏  举报