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

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

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

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

1、生成私钥

  1. openssl genrsa -out rsa_private_key.pem

如下:

  1. -----BEGIN RSA PRIVATE KEY-----
  2. MIICXQIBAAKBgQC6BSDlbRplhMMNZBKHX4xe8AwESpzHVfAcHHsX9FFSMuF91W3c
  3. xgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKwko3tK9Ua691afod1lxORR3Ia
  4. Z8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41GqvOw3G9leClSvjVnSwIDAQAB
  5. AoGAagooYYCbTomq4wRL562ZCDmQsBWUX7Fmia/Wn6YfgVsN3bx/vx2Gld2AOIMB
  6. ZVJXzzYGUYk7LV9bu/vKudRwWvtPIYzxPEOBoaFGPrEPTAfDVwOklhzTz3zDmCHi
  7. hLSpjQXYCG7boZ6G96NfKyTRSGPqgovHY3+KJvd/gAoZqOkCQQDt9YXfanpuwZx1
  8. 7MYjMEvoh5UY1vSsV72ts3/gTVEUkWdfXHj0XhyRhOL9Qu99TGZcoEwecygoUPLm
  9. dySyiXl/AkEAyB+JP8W7oTG/HTHc5QGDfwlPjIH1o5YG2I8Tp02i3G7OTJc/b9/+
  10. SPxcKsT78xrgox5ModPKBX50F783Y2DANQJBAKY4Mjp882b4gWVybnlYHD4ir0h5
  11. ptHYPFvgnfu9plx6sT3Qp4DzWHth2vlUT1w0CPC83E8M28lFula4dP7tvtsCQQCt
  12. a2asdNVbophS3FrnuKAS/iaJRDVxRRk5oQMPACAZlYwAozC96gWZidb02S7cRHZV
  13. 5HPT6IwwppxD19hPrg/hAkBdnl+BGF/eRw80OHJtZBkLnY4Hx9YGft9AyIp3SB1z
  14. QDhaWHgFA+8lED+bWTvJxt/IMmzyYBaGnZbEjCECKZLD
  15. -----END RSA PRIVATE KEY-----

2、生成公钥

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

如下:

  1. -----BEGIN PUBLIC KEY-----
  2. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE
  3. SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw
  4. ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G
  5. qvOw3G9leClSvjVnSwIDAQAB
  6. -----END PUBLIC KEY-----

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

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

如下:

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

4.JAVA版本加解密:

  1. import org.apache.commons.codec.binary.Base64;
  2. import org.apache.commons.lang3.ArrayUtils;
  3.  
  4. import javax.crypto.Cipher;
  5. import java.security.*;
  6. import java.security.spec.PKCS8EncodedKeySpec;
  7. import java.security.spec.X509EncodedKeySpec;
  8.  
  9. public class RSAUtils {
  10.  
  11. /**
  12. * RSA最大加密明文大小
  13. */
  14. private static final int MAX_ENCRYPT_BLOCK = 117;
  15.  
  16. /**
  17. * RSA最大解密密文大小
  18. */
  19. private static final int MAX_DECRYPT_BLOCK = 128;
  20.  
  21. public static final String SIGN_ALGORITHMS = "SHA256withRSA";
  22.  
  23. private static String ALGORITHM_RSA = "RSA";
  24.  
  25. /**
  26. * 使用公钥将数据加密
  27. * @param sourceData
  28. * @param publicKey
  29. * @return
  30. */
  31. public static String publicEncrypt(String sourceData, String publicKey){
  32. return rsaEncrypt(sourceData,publicKey,false);
  33. }
  34.  
  35. /**
  36. * 使用私钥将数据加密
  37. * @param sourceData
  38. * @param privateKey
  39. * @return
  40. */
  41. public static String privateEncrypt(String sourceData, String privateKey){
  42. return rsaEncrypt(sourceData,privateKey,true);
  43. }
  44.  
  45. /**
  46. * 使用公钥解密
  47. * @param encryptedData
  48. * @param privateKey
  49. * @return
  50. */
  51. public static String publicDecrypt(String encryptedData, String privateKey) {
  52. return rsaDecrypt(encryptedData,privateKey,false);
  53. }
  54.  
  55. /**
  56. * 使用私钥解密
  57. * @param encryptedData
  58. * @param privateKey
  59. * @return
  60. */
  61. public static String privateDecrypt(String encryptedData, String privateKey) {
  62. return rsaDecrypt(encryptedData,privateKey,true);
  63. }
  64.  
  65. protected static String rsaEncrypt(String sourceData, String key,boolean isPrivate){
  66. try {
  67. Key key1 = isPrivate ? loadPrivateKey(key) : loadPublicKey(key);
  68. byte[] data = sourceData.getBytes();
  69. byte[] dataReturn = new byte[0];
  70. Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
  71. cipher.init(Cipher.ENCRYPT_MODE, key1);
  72.  
  73. // 加密时超过117字节就报错。为此采用分段加密的办法来加密
  74. StringBuilder sb = new StringBuilder();
  75. for (int i = 0; i < data.length; i += MAX_ENCRYPT_BLOCK) {
  76. byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i,i + MAX_ENCRYPT_BLOCK));
  77. sb.append(new String(doFinal));
  78. dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
  79. }
  80.  
  81. return Base64.encodeBase64URLSafeString(dataReturn);
  82. } catch (Exception e) {
  83. e.printStackTrace();
  84. return null;
  85. }
  86. }
  87.  
  88. protected static String rsaDecrypt(String encryptedData, String key,boolean isPrivate){
  89. try {
  90. Key key1 = isPrivate ? loadPrivateKey(key) : loadPublicKey(key);
  91. byte[] data = Base64.decodeBase64(encryptedData);
  92.  
  93. Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
  94. cipher.init(Cipher.DECRYPT_MODE, key1);
  95.  
  96. // 解密时超过128字节就报错。为此采用分段解密的办法来解密
  97. byte[] dataReturn = new byte[0];
  98. for (int i = 0; i < data.length; i += MAX_DECRYPT_BLOCK) {
  99. byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + MAX_DECRYPT_BLOCK));
  100. dataReturn = ArrayUtils.addAll(dataReturn, doFinal);
  101. }
  102.  
  103. return new String(dataReturn);
  104. } catch (Exception e) {
  105. e.printStackTrace();
  106. return null;
  107. }
  108. }
  109.  
  110. /**
  111. * 私钥加签名
  112. * @param encryptData
  113. * @param privateKey
  114. * @return
  115. */
  116. public static String rsaSign(String encryptData, String privateKey) {
  117. try {
  118. Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
  119. signature.initSign(loadPrivateKey(privateKey));
  120. signature.update(encryptData.getBytes());
  121. byte[] signed = signature.sign();
  122. return Base64.encodeBase64URLSafeString(signed);
  123. } catch (Exception e) {
  124. e.printStackTrace();
  125. }
  126. return null;
  127. }
  128.  
  129. /**
  130. * 公钥验签
  131. * @param encryptStr
  132. * @param sign
  133. * @param publicKey
  134. * @return
  135. * @throws Exception
  136. */
  137. public static boolean verifySign(String encryptStr, String sign, String publicKey)throws Exception {
  138. try {
  139. Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
  140. signature.initVerify(loadPublicKey(publicKey));
  141. signature.update(encryptStr.getBytes());
  142. return signature.verify(Base64.decodeBase64(sign));
  143. } catch (NoSuchAlgorithmException e) {
  144. throw new Exception(String.format("验证数字签名时没有[%s]此类算法", SIGN_ALGORITHMS));
  145. } catch (InvalidKeyException e) {
  146. throw new Exception("验证数字签名时公钥无效");
  147. } catch (SignatureException e) {
  148. throw new Exception("验证数字签名时出现异常");
  149. }
  150. }
  151.  
  152. public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
  153. byte[] buffer = Base64.decodeBase64(publicKeyStr);
  154. KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
  155. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
  156. return keyFactory.generatePublic(keySpec);
  157. }
  158.  
  159. public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
  160. byte[] buffer = Base64.decodeBase64(privateKeyStr);
  161. PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
  162. KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
  163. return keyFactory.generatePrivate(keySpec);
  164. }
  165.  
  166. public static String urlsafe_encode (String encryptStr){
  167. return encryptStr.replaceAll("\\+","-").replaceAll("/","_").replaceAll("=","").replaceAll("(\r\n|\r|\n|\n\r)","");
  168.  
  169. }
  170.  
  171. public static String urlsafe_decode(String encryptStr){
  172. encryptStr= encryptStr.replaceAll("-","+").replaceAll("_","/");
  173. int mob = encryptStr.length()%4;
  174. if(mob>0){
  175. encryptStr+="====".substring(mob);
  176. }
  177. return encryptStr;
  178. }
  179.  
  180. public static void main(String[ ] asdfs) throws Exception {
  181. String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE" +
  182. "SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw" +
  183. "ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G" +
  184. "qvOw3G9leClSvjVnSwIDAQAB";
  185. String privateKeyStr = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALoFIOVtGmWEww1k" +
  186. "EodfjF7wDARKnMdV8Bwcexf0UVIy4X3VbdzGBP+Dmf6qUssXMITeFYb/Jfk0wDFH" +
  187. "iZLcyWHJcrCSje0r1Rrr3Vp+h3WXE5FHchpnydXu/kG/zLgkN7gTf9/9tAgbOuha" +
  188. "InSxdNw7jUaq87Dcb2V4KVK+NWdLAgMBAAECgYBqCihhgJtOiarjBEvnrZkIOZCw" +
  189. "FZRfsWaJr9afph+BWw3dvH+/HYaV3YA4gwFlUlfPNgZRiTstX1u7+8q51HBa+08h" +
  190. "jPE8Q4GhoUY+sQ9MB8NXA6SWHNPPfMOYIeKEtKmNBdgIbtuhnob3o18rJNFIY+qC" +
  191. "i8djf4om93+AChmo6QJBAO31hd9qem7BnHXsxiMwS+iHlRjW9KxXva2zf+BNURSR" +
  192. "Z19cePReHJGE4v1C731MZlygTB5zKChQ8uZ3JLKJeX8CQQDIH4k/xbuhMb8dMdzl" +
  193. "AYN/CU+MgfWjlgbYjxOnTaLcbs5Mlz9v3/5I/FwqxPvzGuCjHkyh08oFfnQXvzdj" +
  194. "YMA1AkEApjgyOnzzZviBZXJueVgcPiKvSHmm0dg8W+Cd+72mXHqxPdCngPNYe2Ha" +
  195. "+VRPXDQI8LzcTwzbyUW6Vrh0/u2+2wJBAK1rZqx01VuimFLcWue4oBL+JolENXFF" +
  196. "GTmhAw8AIBmVjACjML3qBZmJ1vTZLtxEdlXkc9PojDCmnEPX2E+uD+ECQF2eX4EY" +
  197. "X95HDzQ4cm1kGQudjgfH1gZ+30DIindIHXNAOFpYeAUD7yUQP5tZO8nG38gybPJg" +
  198. "FoadlsSMIQIpksM=";
  199.  
  200. //加密
  201. String data = "i like java";
  202. String privateEncryptStr = RSAUtils.privateEncrypt(data, privateKeyStr);
  203. String publicEncryptStr = RSAUtils.publicEncrypt(data, publicKeyStr);
  204. String privateEncryptSign = RSAUtils.rsaSign(privateEncryptStr,privateKeyStr);
  205. String publicEncryptSign = RSAUtils.rsaSign(publicEncryptStr,privateKeyStr);
  206.  
  207. System.out.println("source:" + data);
  208. System.out.println("private encryptStr: " + privateEncryptStr);
  209. System.out.println("public encryptStr: " + publicEncryptStr);
  210. System.out.println("private encrypt sign: " + privateEncryptSign);
  211. System.out.println("public encrypt sign: " + publicEncryptSign);
  212. System.out.println("public decrypt:" + RSAUtils.publicDecrypt(privateEncryptStr, publicKeyStr));
  213. System.out.println("private decrypt:" + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
  214. System.out.println("verifySign1: " + RSAUtils.verifySign(privateEncryptStr,privateEncryptSign,publicKeyStr));
  215. System.out.println("verifySign2: " + RSAUtils.verifySign(publicEncryptStr,publicEncryptSign,publicKeyStr));
  216.  
  217. System.out.println("\r\n");
  218. publicEncryptStr = "WopnO2LnolZ7XpOwA_ktOhfkkaQQJQgkJudk3ZH_-ob36GQFv968nE1UBXxNekA9pIHBcvcl0ZWfwFhk-kyOF2FmQvpPY9LkqiCV0T32vhJet0n93ti2PBoFILxvChjzdOgSG9M0flH78Vm696Q4mHo7VMt_XMoHDTd3Rbagvt8";
  219. privateEncryptStr = "Fwb5BtLRveCWbx7FkXarl1zVOdwDvbDTl7gv-vPHXpj-T2wm9GlUDn3X0wnHHXkE8cqAT6PcE0g0ide6beP9_ysHMLgnC6wVqkomIKsi6C9TcGd4d6XQBjeJgdgccvDcD-7pcKrV9W-_Z7jkYkwwrjPGPd_uckEHR_cDXyOX4PU";
  220. System.out.println("php >>>> private decrypt: " + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
  221. System.out.println("php >>>> public decrypt: " + RSAUtils.publicDecrypt(privateEncryptStr, publicKeyStr));
  222.  
  223. publicEncryptStr = "T2LFtY3dF_b6OBO07BN-3LtMSEBZqDukovDZ4HGCff8wosvlowf6IFJ3U7LFBIeHfiHBKiFuAV8-pFltCfTXtA4AwgVUnwbBMBWBfIJiLDi02ev30V-5BcYEuSF-cEdnSUd7WecrX4rHhzYLueGuj8H6c7RRbSbrJ6_3EFfU-K0";
  224. System.out.println("js >>>> private decrypt: " + RSAUtils.privateDecrypt(publicEncryptStr, privateKeyStr));
  225. }
  226. }

输出如下:

  1. source: i like java
  2. private encryptStr: fHG5JMpTTF-KzrPCp827opRy3BvqmVIpIZS4gVuWqY5NeLsgoLxdrq3SaxUp_oBQ9pVqNlEiU9SIwbqJDjIqjHsCtVMOLoEdWicib_wCaoB16veKTEC4GnvviJwlS5IedH27oWGHKTTc6Ii5cLiQncjDAadvm0KCdC74yrwPqnc
  3. public encryptStr: raoQQsfN0KBfPAMRWnxr9kFPvJ6BgQ7PRBCMnz0nWsH03sD4IdlMvKpj78BHe7V7Ga1HZHyDxuJhVaJ0T5qKl8qHXzvKquzNtdMru7G4X9o8ylzkGxJLg-HYCWOrsZ77ZMaKoV9p-TCf-yMI21OpL_5JGot-XNfVVPkmg0z9FW0
  4. private encrypt sign: jlJvXY5t8KesDi3WaPr71jj2BigHLDr3b827Jl9xspbecdUjPB44Xe3sjWnzvFDLpKJGiNTvqE-Qyu3FZpG_NyI5yhVrAQgZmyYfVywmeDDsTOQYk1xP0UEfFgB0MXsFdlfSdMu5JcR5kgC5Xl5jds1b0Z2Nq7gQ-bvFJQcuHgU
  5. public encrypt sign: ngN2kQppfITyn5yAfNc1c-ofK20trKJWXIjlaJhWtm7s2jzv5rcsPY5JH06CMAIIbnKGIUcoVvMeKavAIVFb4G_h3CvXIYnxMjQL19Op-SbtyGNwT-rZzTEP8tKfxFRVm7SrHHDz2s287S3vqQz9vGEGNmgDHEdrCfHBmmoFkQA
  6. public decrypt: i like java
  7. private decrypt: i like java
  8. verifySign1: true
  9. verifySign2: true
  10.  
  11. php >>>> private decrypt: i like php
  12. php >>>> public decrypt: i like php
  13.  
  14. js >>>> private decrypt: i like JS

5.PHP版本加解密

  1. <?php
  2.  
  3. $private_key = <<<KEY
  4. -----BEGIN RSA PRIVATE KEY-----
  5. MIICXQIBAAKBgQC6BSDlbRplhMMNZBKHX4xe8AwESpzHVfAcHHsX9FFSMuF91W3c
  6. xgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKwko3tK9Ua691afod1lxORR3Ia
  7. Z8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41GqvOw3G9leClSvjVnSwIDAQAB
  8. AoGAagooYYCbTomq4wRL562ZCDmQsBWUX7Fmia/Wn6YfgVsN3bx/vx2Gld2AOIMB
  9. ZVJXzzYGUYk7LV9bu/vKudRwWvtPIYzxPEOBoaFGPrEPTAfDVwOklhzTz3zDmCHi
  10. hLSpjQXYCG7boZ6G96NfKyTRSGPqgovHY3+KJvd/gAoZqOkCQQDt9YXfanpuwZx1
  11. 7MYjMEvoh5UY1vSsV72ts3/gTVEUkWdfXHj0XhyRhOL9Qu99TGZcoEwecygoUPLm
  12. dySyiXl/AkEAyB+JP8W7oTG/HTHc5QGDfwlPjIH1o5YG2I8Tp02i3G7OTJc/b9/+
  13. SPxcKsT78xrgox5ModPKBX50F783Y2DANQJBAKY4Mjp882b4gWVybnlYHD4ir0h5
  14. ptHYPFvgnfu9plx6sT3Qp4DzWHth2vlUT1w0CPC83E8M28lFula4dP7tvtsCQQCt
  15. a2asdNVbophS3FrnuKAS/iaJRDVxRRk5oQMPACAZlYwAozC96gWZidb02S7cRHZV
  16. 5HPT6IwwppxD19hPrg/hAkBdnl+BGF/eRw80OHJtZBkLnY4Hx9YGft9AyIp3SB1z
  17. QDhaWHgFA+8lED+bWTvJxt/IMmzyYBaGnZbEjCECKZLD
  18. -----END RSA PRIVATE KEY-----
  19. KEY;
  20.  
  21. $private8_key = <<<KEY
  22. -----BEGIN PRIVATE KEY-----
  23. MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALoFIOVtGmWEww1k
  24. EodfjF7wDARKnMdV8Bwcexf0UVIy4X3VbdzGBP+Dmf6qUssXMITeFYb/Jfk0wDFH
  25. iZLcyWHJcrCSje0r1Rrr3Vp+h3WXE5FHchpnydXu/kG/zLgkN7gTf9/9tAgbOuha
  26. InSxdNw7jUaq87Dcb2V4KVK+NWdLAgMBAAECgYBqCihhgJtOiarjBEvnrZkIOZCw
  27. FZRfsWaJr9afph+BWw3dvH+/HYaV3YA4gwFlUlfPNgZRiTstX1u7+8q51HBa+08h
  28. jPE8Q4GhoUY+sQ9MB8NXA6SWHNPPfMOYIeKEtKmNBdgIbtuhnob3o18rJNFIY+qC
  29. i8djf4om93+AChmo6QJBAO31hd9qem7BnHXsxiMwS+iHlRjW9KxXva2zf+BNURSR
  30. Z19cePReHJGE4v1C731MZlygTB5zKChQ8uZ3JLKJeX8CQQDIH4k/xbuhMb8dMdzl
  31. AYN/CU+MgfWjlgbYjxOnTaLcbs5Mlz9v3/5I/FwqxPvzGuCjHkyh08oFfnQXvzdj
  32. YMA1AkEApjgyOnzzZviBZXJueVgcPiKvSHmm0dg8W+Cd+72mXHqxPdCngPNYe2Ha
  33. +VRPXDQI8LzcTwzbyUW6Vrh0/u2+2wJBAK1rZqx01VuimFLcWue4oBL+JolENXFF
  34. GTmhAw8AIBmVjACjML3qBZmJ1vTZLtxEdlXkc9PojDCmnEPX2E+uD+ECQF2eX4EY
  35. X95HDzQ4cm1kGQudjgfH1gZ+30DIindIHXNAOFpYeAUD7yUQP5tZO8nG38gybPJg
  36. FoadlsSMIQIpksM=
  37. -----END PRIVATE KEY-----
  38. KEY;
  39.  
  40. $public_key = <<<KEY
  41. -----BEGIN PUBLIC KEY-----
  42. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE
  43. SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw
  44. ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G
  45. qvOw3G9leClSvjVnSwIDAQAB
  46. -----END PUBLIC KEY-----
  47. KEY;
  48.  
  49. $data = 'i like php';
  50. //使用公钥将数据加密
  51. $encrypt_data = RsaUtils::publicEncrypt($data,$public_key);
  52. //使用私钥将数据解密
  53. $decrypt_data = RsaUtils::privateDecrypt($encrypt_data,$private_key);
  54.  
  55. echo 'public encrypt data:'.$encrypt_data.PHP_EOL;
  56. echo 'private decrypt data:'.$decrypt_data.PHP_EOL;
  57.  
  58. //使用私钥将数据加密
  59. $encrypt_data = RsaUtils::privateEncrypt($data,$private_key);
  60. //使用私钥将加密数据加签
  61. $private_encrypt_sign = RsaUtils::rsaSign($encrypt_data,$private_key);
  62. //使用公钥解签
  63. $public_check_sign = RsaUtils::verifySign($encrypt_data,$private_encrypt_sign,$public_key);
  64. //使用公钥将数据解密
  65. $decrypt_data = RsaUtils::publicDecrypt($encrypt_data,$public_key);
  66.  
  67. echo 'private encrypt data: '.$encrypt_data.PHP_EOL;
  68. echo 'private encrypt sign: '.$private_encrypt_sign.PHP_EOL;
  69. echo 'public check sign: '.$public_check_sign.PHP_EOL;
  70. echo 'public decrypt data: '.$decrypt_data.PHP_EOL;
  71.  
  72. //验证java加密解密方法
  73. $private_encrypt_data = 'fHG5JMpTTF-KzrPCp827opRy3BvqmVIpIZS4gVuWqY5NeLsgoLxdrq3SaxUp_oBQ9pVqNlEiU9SIwbqJDjIqjHsCtVMOLoEdWicib_wCaoB16veKTEC4GnvviJwlS5IedH27oWGHKTTc6Ii5cLiQncjDAadvm0KCdC74yrwPqnc';
  74. $public_decrypt_data = RsaUtils::publicDecrypt($private_encrypt_data,$public_key);
  75. $sign_data1 = 'jlJvXY5t8KesDi3WaPr71jj2BigHLDr3b827Jl9xspbecdUjPB44Xe3sjWnzvFDLpKJGiNTvqE-Qyu3FZpG_NyI5yhVrAQgZmyYfVywmeDDsTOQYk1xP0UEfFgB0MXsFdlfSdMu5JcR5kgC5Xl5jds1b0Z2Nq7gQ-bvFJQcuHgU';
  76. $verify_sign1 = RsaUtils::verifySign($private_encrypt_data,$sign_data1,$public_key);
  77.  
  78. $public_encrypt_data = 'raoQQsfN0KBfPAMRWnxr9kFPvJ6BgQ7PRBCMnz0nWsH03sD4IdlMvKpj78BHe7V7Ga1HZHyDxuJhVaJ0T5qKl8qHXzvKquzNtdMru7G4X9o8ylzkGxJLg-HYCWOrsZ77ZMaKoV9p-TCf-yMI21OpL_5JGot-XNfVVPkmg0z9FW0';
  79. $private_decrypt_data = RsaUtils::privateDecrypt($public_encrypt_data, $private_key);
  80. $sign_data2 = 'ngN2kQppfITyn5yAfNc1c-ofK20trKJWXIjlaJhWtm7s2jzv5rcsPY5JH06CMAIIbnKGIUcoVvMeKavAIVFb4G_h3CvXIYnxMjQL19Op-SbtyGNwT-rZzTEP8tKfxFRVm7SrHHDz2s287S3vqQz9vGEGNmgDHEdrCfHBmmoFkQA';
  81. $verify_sign2 = RsaUtils::verifySign($public_encrypt_data,$sign_data2,$public_key);
  82.  
  83. echo PHP_EOL;
  84. echo 'public_decrypt_data: '.$public_decrypt_data.PHP_EOL;
  85. echo 'verifySign1: '. $verify_sign1.PHP_EOL;
  86.  
  87. echo 'private_decrypt_data: '.$private_decrypt_data.PHP_EOL;
  88. echo 'verifySign2: '. $verify_sign2.PHP_EOL;
  89.  
  90. $public_encrypt_data = 'T2LFtY3dF_b6OBO07BN-3LtMSEBZqDukovDZ4HGCff8wosvlowf6IFJ3U7LFBIeHfiHBKiFuAV8-pFltCfTXtA4AwgVUnwbBMBWBfIJiLDi02ev30V-5BcYEuSF-cEdnSUd7WecrX4rHhzYLueGuj8H6c7RRbSbrJ6_3EFfU-K0';
  91. $private_decrypt_data = RsaUtils::privateDecrypt($public_encrypt_data,$private_key);
  92. echo PHP_EOL;
  93. echo 'private_decrypt_data: '.$private_decrypt_data.PHP_EOL;
  94.  
  95. class RsaUtils{
  96.  
  97. /**
  98. * 签名算法,SHA256WithRSA
  99. */
  100. private const SIGNATURE_ALGORITHM = OPENSSL_ALGO_SHA256;
  101.  
  102. /**
  103. * RSA最大加密明文大小
  104. */
  105. private const MAX_ENCRYPT_BLOCK = 117;
  106.  
  107. /**
  108. * RSA最大解密密文大小
  109. */
  110. private const MAX_DECRYPT_BLOCK = 128;
  111.  
  112. /**
  113. * 使用公钥将数据加密
  114. * @param $data string 需要加密的数据
  115. * @param $publicKey string 公钥
  116. * @return string 返回加密串(base64编码)
  117. */
  118. public static function publicEncrypt($data,$publicKey){
  119. $data = str_split($data, self::MAX_ENCRYPT_BLOCK);
  120.  
  121. $encrypted = '';
  122. foreach($data as & $chunk){
  123. if(!openssl_public_encrypt($chunk, $encryptData, $publicKey)){
  124. return '';
  125. }else{
  126. $encrypted .= $encryptData;
  127. }
  128. }
  129. return self::urlSafeBase64encode($encrypted);
  130. }
  131.  
  132. /**
  133. * 使用私钥解密
  134. * @param $data string 需要解密的数据
  135. * @param $privateKey string 私钥
  136. * @return string 返回解密串
  137. */
  138. public static function privateDecrypt($data,$privateKey){
  139. $data = str_split(self::urlSafeBase64decode($data), self::MAX_DECRYPT_BLOCK);
  140.  
  141. $decrypted = '';
  142. foreach($data as & $chunk){
  143. if(!openssl_private_decrypt($chunk, $decryptData, $privateKey)){
  144. return '';
  145. }else{
  146. $decrypted .= $decryptData;
  147. }
  148. }
  149. return $decrypted;
  150. }
  151.  
  152. /**
  153. * 使用私钥将数据加密
  154. * @param $data string 需要加密的数据
  155. * @param $privateKey string 私钥
  156. * @return string 返回加密串(base64编码)
  157. */
  158. public static function privateEncrypt($data,$privateKey){
  159. $data = str_split($data, self::MAX_ENCRYPT_BLOCK);
  160.  
  161. $encrypted = '';
  162. foreach($data as & $chunk){
  163. if(!openssl_private_encrypt($chunk, $encryptData, $privateKey)){
  164. return '';
  165. }else{
  166. $encrypted .= $encryptData;
  167. }
  168. }
  169. return self::urlSafeBase64encode($encrypted);
  170. }
  171.  
  172. /**
  173. * 使用公钥解密
  174. * @param $data string 需要解密的数据
  175. * @param $publicKey string 公钥
  176. * @return string 返回解密串
  177. */
  178. public static function publicDecrypt($data,$publicKey){
  179. $data = str_split(self::urlSafeBase64decode($data), self::MAX_DECRYPT_BLOCK);
  180.  
  181. $decrypted = '';
  182. foreach($data as & $chunk){
  183. if(!openssl_public_decrypt($chunk, $decryptData, $publicKey)){
  184. return '';
  185. }else{
  186. $decrypted .= $decryptData;
  187. }
  188. }
  189. return $decrypted;
  190. }
  191.  
  192. /**
  193. * 私钥加签名
  194. * @param $data 被加签数据
  195. * @param $privateKey 私钥
  196. * @return mixed|string
  197. */
  198. public static function rsaSign($data, $privateKey){
  199. if(openssl_sign($data, $sign, $privateKey, self::SIGNATURE_ALGORITHM)){
  200. return self::urlSafeBase64encode($sign);
  201. }
  202. return '';
  203. }
  204.  
  205. /**
  206. * 公钥验签
  207. * @param $data 被加签数据
  208. * @param $sign 签名
  209. * @param $publicKey 公钥
  210. * @return bool
  211. */
  212. public static function verifySign($data, $sign, $publicKey):bool {
  213. return (1 == openssl_verify($data, self::urlSafeBase64decode($sign), $publicKey, self::SIGNATURE_ALGORITHM));
  214. }
  215.  
  216. /**
  217. * url base64编码
  218. * @param $string
  219. * @return mixed|string
  220. */
  221. public static function urlSafeBase64encode($string){
  222. $data = str_replace(array('+','/','='), array( '-','_',''), base64_encode($string));
  223. return $data;
  224. }
  225.  
  226. /**
  227. * url base64解码
  228. * @param $string
  229. * @return bool|string
  230. */
  231. public static function urlSafeBase64decode($string){
  232. $data = str_replace(array('-','_'), array('+','/'), $string);
  233. $mod4 = strlen($data) % 4;
  234. if($mod4){
  235. $data .= substr('====', $mod4);
  236. }
  237. return base64_decode($data);
  238. }
  239. }

输出如下:

  1. public encrypt data: WopnO2LnolZ7XpOwA_ktOhfkkaQQJQgkJudk3ZH_-ob36GQFv968nE1UBXxNekA9pIHBcvcl0ZWfwFhk-kyOF2FmQvpPY9LkqiCV0T32vhJet0n93ti2PBoFILxvChjzdOgSG9M0flH78Vm696Q4mHo7VMt_XMoHDTd3Rbagvt8
  2. private decrypt data: i like php
  3. public encrypt data: Fwb5BtLRveCWbx7FkXarl1zVOdwDvbDTl7gv-vPHXpj-T2wm9GlUDn3X0wnHHXkE8cqAT6PcE0g0ide6beP9_ysHMLgnC6wVqkomIKsi6C9TcGd4d6XQBjeJgdgccvDcD-7pcKrV9W-_Z7jkYkwwrjPGPd_uckEHR_cDXyOX4PU
  4. private rsa sign: T-I3KLkBEMRi9YdflyjNZxh_IhEC2mG4vFaq5FeFzs03l7ojtmf3pXFOwjz6qbHUwIJ-tjIMVammfCrYKa0AjMAX_L7-99_EUPmMvmjXS_8z0aZuY5dZPgRCBxklKem56r0qss-iSGTGsh3eivhUiHvtRTBXhtbkpjjlkkqXy-k
  5. public check sign: 1
  6. private decrypt data: i like php
  7. public_decrypt_data: i like java
  8. verifySign1: 1
  9. private_decrypt_data: i like java
  10. verifySign2: 1
  11.  
  12. private_decrypt_data: i like JS

6.JS版本加解密

  1. var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  2. var b64pad = "=";
  3.  
  4. var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
  5.  
  6. //整型转字符串
  7. function int2char(n) {
  8. return BI_RM.charAt(n);
  9. }
  10.  
  11. //十六进制转Base64字符串
  12. function hex2b64(h) {
  13. var i;
  14. var c;
  15. var ret = "";
  16. for (i = 0; i + 3 <= h.length; i += 3) {
  17. c = parseInt(h.substring(i, i + 3), 16);
  18. ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
  19. }
  20. if (i + 1 == h.length) {
  21. c = parseInt(h.substring(i, i + 1), 16);
  22. ret += b64map.charAt(c << 2);
  23. }
  24. else if (i + 2 == h.length) {
  25. c = parseInt(h.substring(i, i + 2), 16);
  26. ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
  27. }
  28. while ((ret.length & 3) > 0) {
  29. ret += b64pad;
  30. }
  31. return ret;
  32. }
  33.  
  34. //Base64字符串转十六进制
  35. function b64tohex(s) {
  36. var ret = "";
  37. var i;
  38. var k = 0; // b64 state, 0-3
  39. var slop = 0;
  40. for (i = 0; i < s.length; ++i) {
  41. if (s.charAt(i) == b64pad) {
  42. break;
  43. }
  44. var v = b64map.indexOf(s.charAt(i));
  45. if (v < 0) {
  46. continue;
  47. }
  48. if (k == 0) {
  49. ret += int2char(v >> 2);
  50. slop = v & 3;
  51. k = 1;
  52. }
  53. else if (k == 1) {
  54. ret += int2char((slop << 2) | (v >> 4));
  55. slop = v & 0xf;
  56. k = 2;
  57. }
  58. else if (k == 2) {
  59. ret += int2char(slop);
  60. ret += int2char(v >> 2);
  61. slop = v & 3;
  62. k = 3;
  63. }
  64. else {
  65. ret += int2char((slop << 2) | (v >> 4));
  66. ret += int2char(v & 0xf);
  67. k = 0;
  68. }
  69. }
  70. if (k == 1) {
  71. ret += int2char(slop << 2);
  72. }
  73. return ret;
  74. }
  75.  
  76. //十六进制转字节
  77. function hexToBytes(hex) {
  78. for (var bytes = [], c = 0; c < hex.length; c += 2)
  79. bytes.push(parseInt(hex.substr(c, 2), 16));
  80. return bytes;
  81. }
  82.  
  83. //字节转十六进制
  84. function bytesToHex(bytes) {
  85. for (var hex = [], i = 0; i < bytes.length; i++) {
  86. hex.push((bytes[i] >>> 4).toString(16));
  87. hex.push((bytes[i] & 0xF).toString(16));
  88. }
  89. return hex.join("");
  90. }
  91.  
  92. String.prototype.replaceAllStr=function(f,e){
  93. var reg=new RegExp(f,"g");
  94. return this.replace(reg,e);
  95. }
  96.  
  97. function urlsafeEncode(e) {
  98. return e.replaceAllStr("\\+","-").replaceAllStr("/","_").replaceAllStr("=","");
  99. }
  100.  
  101. function urlsafeDecode(e) {
  102. e = e.replaceAllStr("-","+").replaceAllStr("_","/");
  103. var mob = e.length%4;
  104. if(mob>0){
  105. e += "====".substr(mob);
  106. }
  107. return e;
  108. }
  109.  
  110. //长字符串加密
  111. JSEncrypt.prototype.encryptLong = function (string) {
  112. var k = this.getKey();
  113. //var MAX_ENCRYPT_BLOCK = (((k.n.bitLength() + 7) >> 3) - 11);
  114. var MAX_ENCRYPT_BLOCK = 117;
  115.  
  116. try {
  117. var lt = "";
  118. var ct = "";
  119. //RSA每次加密117bytes,需要辅助方法判断字符串截取位置
  120. //1.获取字符串截取点
  121. var bytes = new Array();
  122. bytes.push(0);
  123. var byteNo = 0;
  124. var len, c;
  125. len = string.length;
  126.  
  127. var temp = 0;
  128. for (var i = 0; i < len; i++) {
  129. c = string.charCodeAt(i);
  130. if (c >= 0x010000 && c <= 0x10FFFF) {
  131. byteNo += 4;
  132. } else if (c >= 0x000800 && c <= 0x00FFFF) {
  133. byteNo += 3;
  134. } else if (c >= 0x000080 && c <= 0x0007FF) {
  135. byteNo += 2;
  136. } else {
  137. byteNo += 1;
  138. }
  139. if ((byteNo % MAX_ENCRYPT_BLOCK) >= 114 || (byteNo % MAX_ENCRYPT_BLOCK) == 0) {
  140. if (byteNo - temp >= 114) {
  141. bytes.push(i);
  142. temp = byteNo;
  143. }
  144. }
  145. }
  146.  
  147. //2.截取字符串并分段加密
  148. if (bytes.length > 1) {
  149. for (var i = 0; i < bytes.length - 1; i++) {
  150. var str;
  151. if (i == 0) {
  152. str = string.substring(0, bytes[i + 1] + 1);
  153. } else {
  154. str = string.substring(bytes[i] + 1, bytes[i + 1] + 1);
  155. }
  156. var t1 = k.encrypt(str);
  157. ct += t1;
  158. }
  159. ;
  160. if (bytes[bytes.length - 1] != string.length - 1) {
  161. var lastStr = string.substring(bytes[bytes.length - 1] + 1);
  162. ct += k.encrypt(lastStr);
  163. }
  164. return hex2b64(ct);
  165. }
  166. var t = k.encrypt(string);
  167. var y = hex2b64(t);
  168. return y;
  169. } catch (ex) {
  170. return false;
  171. }
  172. };
  173.  
  174. //长字符串解密
  175. JSEncrypt.prototype.decryptLong = function (string) {
  176. var k = this.getKey();
  177. // var MAX_DECRYPT_BLOCK = ((k.n.bitLength()+7)>>3);
  178. var MAX_DECRYPT_BLOCK = 128;
  179. try {
  180. var ct = "";
  181. var t1;
  182. var bufTmp;
  183. var hexTmp;
  184. var str = b64tohex(string);
  185. var buf = hexToBytes(str);
  186. var inputLen = buf.length;
  187. //开始长度
  188. var offSet = 0;
  189. //结束长度
  190. var endOffSet = MAX_DECRYPT_BLOCK;
  191.  
  192. //分段加密
  193. while (inputLen - offSet > 0) {
  194. if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
  195. bufTmp = buf.slice(offSet, endOffSet);
  196. hexTmp = bytesToHex(bufTmp);
  197. t1 = k.decrypt(hexTmp);
  198. ct += t1;
  199.  
  200. } else {
  201. bufTmp = buf.slice(offSet, inputLen);
  202. hexTmp = bytesToHex(bufTmp);
  203. t1 = k.decrypt(hexTmp);
  204. ct += t1;
  205.  
  206. }
  207. offSet += MAX_DECRYPT_BLOCK;
  208. endOffSet += MAX_DECRYPT_BLOCK;
  209. }
  210. return ct;
  211. } catch (ex) {
  212. return false;
  213. }
  214. };
  215.  
  216. // Call this code when the page is done loading.
  217. var publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6BSDlbRplhMMNZBKHX4xe8AwE" +
  218. "SpzHVfAcHHsX9FFSMuF91W3cxgT/g5n+qlLLFzCE3hWG/yX5NMAxR4mS3MlhyXKw" +
  219. "ko3tK9Ua691afod1lxORR3IaZ8nV7v5Bv8y4JDe4E3/f/bQIGzroWiJ0sXTcO41G" +
  220. "qvOw3G9leClSvjVnSwIDAQAB";
  221.  
  222. var privateKeyStr = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALoFIOVtGmWEww1k" +
  223. "EodfjF7wDARKnMdV8Bwcexf0UVIy4X3VbdzGBP+Dmf6qUssXMITeFYb/Jfk0wDFH" +
  224. "iZLcyWHJcrCSje0r1Rrr3Vp+h3WXE5FHchpnydXu/kG/zLgkN7gTf9/9tAgbOuha" +
  225. "InSxdNw7jUaq87Dcb2V4KVK+NWdLAgMBAAECgYBqCihhgJtOiarjBEvnrZkIOZCw" +
  226. "FZRfsWaJr9afph+BWw3dvH+/HYaV3YA4gwFlUlfPNgZRiTstX1u7+8q51HBa+08h" +
  227. "jPE8Q4GhoUY+sQ9MB8NXA6SWHNPPfMOYIeKEtKmNBdgIbtuhnob3o18rJNFIY+qC" +
  228. "i8djf4om93+AChmo6QJBAO31hd9qem7BnHXsxiMwS+iHlRjW9KxXva2zf+BNURSR" +
  229. "Z19cePReHJGE4v1C731MZlygTB5zKChQ8uZ3JLKJeX8CQQDIH4k/xbuhMb8dMdzl" +
  230. "AYN/CU+MgfWjlgbYjxOnTaLcbs5Mlz9v3/5I/FwqxPvzGuCjHkyh08oFfnQXvzdj" +
  231. "YMA1AkEApjgyOnzzZviBZXJueVgcPiKvSHmm0dg8W+Cd+72mXHqxPdCngPNYe2Ha" +
  232. "+VRPXDQI8LzcTwzbyUW6Vrh0/u2+2wJBAK1rZqx01VuimFLcWue4oBL+JolENXFF" +
  233. "GTmhAw8AIBmVjACjML3qBZmJ1vTZLtxEdlXkc9PojDCmnEPX2E+uD+ECQF2eX4EY" +
  234. "X95HDzQ4cm1kGQudjgfH1gZ+30DIindIHXNAOFpYeAUD7yUQP5tZO8nG38gybPJg" +
  235. "FoadlsSMIQIpksM=";
  236.  
  237. var sourceStr = "i like JS";
  238.  
  239. //公钥加密
  240. var encrypt = new JSEncrypt();
  241. encrypt.setPublicKey(publicKeyStr);
  242. var encrypted = encrypt.encryptLong(sourceStr);
  243. encrypted = urlsafeEncode(encrypted);
  244.  
  245. //私钥解密
  246. var decrypt = new JSEncrypt();
  247. decrypt.setPrivateKey(privateKeyStr);
  248. var uncrypted = decrypt.decryptLong(urlsafeDecode(encrypted));
  249.  
  250. console.log("public encrypted: ",encrypted);
  251. console.log("private uncrypted: ",uncrypted);

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

jsencrypt.js:

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

输出如下:

  1. public encrypted: T2LFtY3dF_b6OBO07BN-3LtMSEBZqDukovDZ4HGCff8wosvlowf6IFJ3U7LFBIeHfiHBKiFuAV8-pFltCfTXtA4AwgVUnwbBMBWBfIJiLDi02ev30V-5BcYEuSF-cEdnSUd7WecrX4rHhzYLueGuj8H6c7RRbSbrJ6_3EFfU-K0
  2. private uncrypted: i like JS
  3. private uncrypted: i like php
  4. 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

Java & PHP & Javascript 通用 RSA 加密 解密 (长字符串)的更多相关文章

  1. RSA 加密 解密 (长字符串) JAVA JS版本加解密

    系统与系统的数据交互中,有些敏感数据是不能直接明文传输的,所以在发送数据之前要进行加密,在接收到数据时进行解密处理:然而由于系统与系统之间的开发语言不同. 本次需求是生成二维码是通过java生成,由p ...

  2. C# javascript 采用 RSA 加密解密

    C# javascript 采用 RSA 加密解密 1.C#提供公钥 2.javascript用公钥加密 3.C#用私钥解密 4.javascript 类库 https://www.pidder.de ...

  3. RSA加密解密与加签验签

    RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年7月首次在美国公布 ...

  4. 兼容javascript和C#的RSA加密解密算法,对web提交的数据进行加密传输

    Web应用中往往涉及到敏感的数据,由于HTTP协议以明文的形式与服务器进行交互,因此可以通过截获请求的数据包进行分析来盗取有用的信息.虽然https可以对传输的数据进行加密,但是必须要申请证书(一般都 ...

  5. C# Java间进行RSA加密解密交互(三)

    原文:C# Java间进行RSA加密解密交互(三) 接着前面一篇C# Java间进行RSA加密解密交互(二)说吧,在上篇中为了实现 /** * RSA加密 * @param text--待加密的明文 ...

  6. RSA加密解密及数字签名Java实现--转

    RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院 ...

  7. (转)RSA加密解密及数字签名Java实现

    转:http://my.oschina.net/jiangli0502/blog/171263?fromerr=hc4izFe2  RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rives ...

  8. C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法

    因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger ...

  9. C# Java间进行RSA加密解密交互

    原文:C# Java间进行RSA加密解密交互 这里,讲一下RSA算法加解密在C#和Java之间交互的问题,这两天纠结了很久,也看了很多其他人写的文章,颇受裨益,但没能解决我的实际问题,终于,还是被我捣 ...

随机推荐

  1. Java中Double类型的精确计算

    import java.math.BigDecimal; public class DoubleUtil { private static final int DEF_DIV_SCALE = 5; / ...

  2. JQ04

    1.JQ插件 使用插件扩展jq的功能 1)插入插件的步骤: 引入JQ文件,引入插件,若有用到css,需要引入css.使用插件. 2)jquery.color.js <!DOCTYPE html& ...

  3. 阿里云安装nodejs和mongodb

    1) 安装nodejs wget https://nodejs.org/dist/v8.11.3/node-v8.11.3-linux-x64.tar.xz tar -xf node-v8.11.3- ...

  4. 前端工程化系列[05] Yeoman脚手架使用入门

    Yeoman是一款流行的前端的脚手架工具. 脚手架工具可以用来快速的自动生成项目的必要文件和基础文件结构.Yeoman使用的内建命令为yo,同时它自己也是一个包管理工具和自动化任务工具,它基于特定的模 ...

  5. Javascript数组(一)排序

    一.简介首先,我们来看一下JS中sort()和reverse()这两个函数的函数吧reverse();这个函数是用来进行倒序,这个没有什么可说的,所谓倒序就是大的在前面,小的在后面. 比如: var ...

  6. mvn -N和-U的用法

    mvn参数-N.-U理解 关于-N -N,--non-recursive Do not recurse into sub-projects 意思是,不递归到子项目(子模块). 举例: 一个父项目下Fa ...

  7. SpringBoot(十二):springboot2.0.2写测试用例

    导入maven依赖: <dependency> <groupId>junit</groupId> <artifactId>junit</artif ...

  8. phpt5支付宝登陆支付接口解析

    先看效果图 下面的源码来源网络,自己对照修改. 放入一个插件库中,方便管理 创建支付类 1.发起支付 public function init() { $order_id = $_REQUEST['o ...

  9. Google Maps V3 之 路线服务

    概述 您可以使用 DirectionsService 对象计算路线(使用各种交通方式).此对象与 Google Maps API 路线服务进行通信,该服务会接收路线请求并返回计算的结果.您可以自行处理 ...

  10. webstorm intelliJ IDEA phpstorm 设置鼠标滚动改变字体大小

    control+shift+A功能可以搜索对应功能,把mouse:Change font size(Zoom) ...的按钮打开,然后就可以通过 ctrl+鼠标上下滚动调节字体大小