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


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

    本次需求是生成二维码是通过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-----

    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("(
    |
    |
    |
    
    )","");
    
        }
    
        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[ ] asdfs) 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("
    ");
            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));
        }
    }

    输出如下:

    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.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

    6.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
    
    	u00A0u2028u2029";
     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
    
    	u00A0u2028u2029";
     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[^
    ]+
    ([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 = /^(dd)(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 = /^(dddd)(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 += "
    ";
     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)
    ";
     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)
    ";
     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)
    ";
     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 += "
    ";
     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) + "
    ";
    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("
    ").
    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 + "})( +|$
    ?)|(.{1," + width + "})";
    5099             return str.match(RegExp(regex, "g")).join("
    ");
    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-----
    ";
    5108             key += JSEncryptRSAKey.wordwrap(this.getPrivateBaseKeyB64()) + "
    ";
    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-----
    ";
    5119             key += JSEncryptRSAKey.wordwrap(this.getPublicBaseKeyB64()) + "
    ";
    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

    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

  • 相关阅读:
    git常用命令
    Mybatis文档收集
    RocketMQ安装及配置
    vs code 插件收集
    idea中RunDashboard显示
    Error running ‘JeecgSystemApplication‘: Command line is too long. Shorten command line for JeecgSys
    shell脚本 for循环实现文件和目录遍历
    linux一次性解压多个.gz或者.tar.gz文件
    CentOS7挂载磁盘,4T磁盘挂载方法
    windows 安装Nginx服务
  • 原文地址:https://www.cnblogs.com/phpdragon/p/10231724.html
Copyright © 2020-2023  润新知