-
Notifications
You must be signed in to change notification settings - Fork 104
/
ACME-HTML-Web-Browser-Client.html
2998 lines (2708 loc) · 127 KB
/
ACME-HTML-Web-Browser-Client.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<link rel="shortcut icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAe1BMVEUDuu3///8AtuwAue1c0/QAt+1a0vSZ4/gOve4Ju+4AtOzf9v31/P4iw/DS8/yf5fnE7/tNzvMsxvHw+/7t+v7k+P2U4veO4PeA3Pbp+f7h9/3Y9f3I8Pxt1/Vi1PRQz/NDzPIzyPEWv+76/v/3/f+87fqn5/mI3/Z82vb+fQDoAAAA10lEQVQ4y63T2c7CIBCGYWamUwFZurfuy7/e/xVaeySlYmJ8T78nISQgPh0xU2pGZa1EfrazHJz5an2FT3brYKoul4UqAHx5Hhqoq6VTMAc4aER9acDjEviFPd2voP9gKykGVECHkzyBsRzvI+g1jWG5BFDIPXRKjqkcTKUwPISPbvsN9XpqA9DuehXsF4g64APALAY+AHkMVm+CzToNVld1NAmwE0zaJ0DBQughAcxZ66tLAGj6f/f2NdMgewXKGHSPgOTPfG/Dh0vqlAXlluefahaLT3UDvrAKrj7jLKkAAAAASUVORK5CYII=" />
<title>ACME Web Browser Client | ACME客户端H5网页单文件版,在线免费申请签发SSL/TLS通配符泛域名HTTPS证书,支持Let's Encrypt、ZeroSSL,无需账号免登录注册 | Windows macOS Get Wildcard Certificates Online For Free - Single HTML File</title>
</head>
<body>
<script>
var Version="1.0.240804";
console.log("LICENSE: GPL-3.0, https://github.com/xiangyuecn/ACME-HTML-Web-Browser-Client/blob/main/LICENSE");
/***********************************
中英对照翻译主要来自:Chrome自带翻译+百度翻译,由中文翻译成English(作者英文很菜)。
The Chinese-English translation is mainly from: Chrome comes with translation + Baidu translation, which is translated from Chinese to English (the author's English level is very low)
感谢围观本客户端源码,所有功能的代码都在本页面一个文件内,逻辑上会比较长和比较丑(关键地方或多或少有写注释),如感不适,请转头看看旁边的大长腿,再深呼吸一下继续看下一行~
Thank you for watching the source code of this client. The code of all functions is in one file on this page, which is logically long and ugly (more or less comments are written in key places). If you feel uncomfortable, please turn your head and look at the Big Long Legs next to you, take another deep breath and continue to look at the next line~
************************************/
</script>
<div class="main-load" style="padding-top:40vh;text-align:center;font-size:28px">Loading...</div>
<div class="main" style="display:none">
<div class="mainBox acmeReadDirGotoCORSState" style="display:none"></div>
<div class="mainBox">
<span style="font-size:32px;font-weight:bold;color:#03baed;">
<span class="langCN clientNameCN">HTML5网页版ACME客户端</span>
<span class="langEN clientNameEN">ACME Web Browser Client</span>
</span>
<span class="versionBox" style="font-size:14px;color:#03baed;margin-right:80px"></span>
<span style="display:inline-block">
<span class="langCN">开源代码:</span>
<span class="langEN">Open source: </span>
<a href="https://github.com/xiangyuecn/ACME-HTML-Web-Browser-Client" target="_blank">GitHub >></a>
<span class="langCN">
| <a href="https://gitee.com/xiangyuecn/ACME-HTML-Web-Browser-Client" target="_blank">Gitee >></a>
</span>
</span>
<ul class="itemBox feature_ul" style="list-style-type: none;margin:8px 0 0 0;padding:0 8px 0 8px;color:#666">
<li class="langCN"><i>功能用途</i>本网页客户端用于:向 <a href="https://letsencrypt.org/" target="_blank">Let's Encrypt</a>、<a href="https://zerossl.com/" target="_blank">ZeroSSL</a>、<a href="https://pki.goog/" target="_blank">Google</a> 等支持 ACME 协议的证书颁发机构,免费申请获得用于 HTTPS 的 SSL/TLS 域名证书(RSA、ECC/ECDSA),支持多域名和通配符泛域名;只需在现代浏览器上操作即可获得 PEM 格式纯文本的域名证书,不依赖操作系统环境,无需下载和安装软件,纯手动操作,<span class="Bold">只专注于申请获得证书这一件事。</span></li>
<li class="langEN"><i>Functional use</i>This web client is used to: apply for free SSL/TLS domain name certificates (RSA, ECC/ECDSA) for HTTPS from <a href="https://letsencrypt.org/" target="_blank">Let's Encrypt</a> , <a href="https://zerossl.com/" target="_blank">ZeroSSL</a> , <a href="https://pki.goog/" target="_blank">Google</a> and other certificate authorities that support the ACME protocol, and support multiple domain names and wildcard pan-domain names; Simply operate on a modern browser to obtain a domain name certificate in plain text in PEM format, does not depend on the operating system environment, does not need to download and install software, and is purely manual, <span class="Bold">only focus on the only thing that is to apply for and obtain a certificate.</span></li>
<li class="langCN"><i>简单易用</i>点点鼠标 Ctrl+C Ctrl+V 就能完成证书的申请,全程需要的操作少,每一步都有保姆级操作提示,UI友好大气美观;<span class="Bold">本客户端不需要注册账号、更不需要登录。</span></li>
<li class="langEN"><i>Easy to use</i>Click the mouse and Ctrl+C Ctrl+V to complete the certificate application. The whole process requires less operations, and there are nanny level operation prompts at each step; UI friendly, atmospheric and beautiful; <span class="Bold">This client does not need to register an account, and does not need to log in.</span></li>
<li class="langCN"><i>开源项目</i>本网页客户端源码已开源,访问网址由托管仓库提供,源码透明可追溯。</li>
<li class="langEN"><i>Open source project</i>The source code of the client side of this webpage has been open sourced, and the access URL is provided by the hosting warehouse, and the source code is transparent and traceable.</li>
<li class="langCN"><i>单一文件</i>本网页客户端仅一个静态 HTML 文件,不依赖其他任何文件;因此可以直接保存到你本地(右键-另存为),即可通过浏览器打开。</li>
<li class="langEN"><i>A single file</i>This web client is only a single static HTML web page file and does not depend on any other files; therefore, it can be directly saved to your local (right-click - save as), and you can open it through a browser.</li>
<li class="langCN"><i>数据安全</i>除了你指定证书颁发机构的 ACME 接口地址外,本网页客户端不会向其他任何地址发送数据,通过浏览器控制台很容易做到网络数据审查。</li>
<li class="langEN"><i>Data security</i>Except for the ACME interface address of the certificate authority you specify, this web client will not send data to any other address, and it is easy to check the network data through the browser console.</li>
<li class="langCN"><i>系统安全</i>纯网页应用,不会也无法对你的电脑系统做出任何修改。</li>
<li class="langEN"><i>System security</i>Pure web application, will not and cannot make any modification to your computer system.</li>
<li class="langCN" style="color:#cb1d1d"><i style="background:#cb1d1d">证书过期风险提醒</i>由于本网页客户端只能纯手动操作,不支持自动续期,需注意在证书过期前重新生申请新证书(免费证书普遍90天有效期,届时只需重复操作一遍即可),或使用 acme.sh 等客户端自动化续期。</li>
<li class="langEN" style="color:#cb1d1d"><i style="background:#cb1d1d">Certificate Expiration Risk Alert</i>Since this web client can only be operated manually and does not support automatic renewal, you should pay attention to apply for a new certificate before the certificate expires (free certificates are generally valid for 90 days, you only need to repeat the operation at that time), or use acme.sh and other client automatic renewal.</li>
</ul>
<style>
.feature_ul li{margin: 8px 0;}
.feature_ul i{
font-style: normal;
margin-right:8px;
display: inline-block;
vertical-align: middle;
background: #03baed;
color: #fff;
font-size: 14px;
padding: 2px 8px;
border-radius: 99px;
}
</style>
</div>
<div class="mainBox">
<div class="pd itemTitle">
<span class="langCN">步骤一:选择证书颁发机构</span>
<span class="langEN">Step 1: Select a Certificate Authority</span>
</div>
<div class="itemBox">
<div class="pd Bold">
<i class="must">*</i>
<span class="langCN">证书颁发机构 ACME(v2, <a href="https://www.rfc-editor.org/rfc/rfc8555.html" target="_blank">RFC 8555</a>) 服务URL:</span>
<span class="langEN">Certificate Authority ACME (v2, <a href="https://www.rfc-editor.org/rfc/rfc8555.html" target="_blank">RFC 8555</a>) Service URL:</span>
</div>
<div class="pd">
<label><input type="radio" name="choice_acmeURL" value="https://acme-v02.api.letsencrypt.org/directory" desckey="descLetsEncrypt">Let's Encrypt</label>
<label><input type="radio" name="choice_acmeURL" value="https://acme.zerossl.com/v2/DV90/directory" desckey="descZeroSSL">ZeroSSL</label>
<label><input type="radio" name="choice_acmeURL" value="https://dv.acme-v02.api.pki.goog/directory" desckey="descGoogle">Google</label>
<label>
<input type="radio" name="choice_acmeURL" value="manual">
<span class="langCN">手动填写URL</span>
<span class="langEN">Fill in the URL manually</span>
</label>
<label>
<input type="radio" name="choice_acmeURL" value="https://acme-staging-v02.api.letsencrypt.org/directory">
<span class="langCN">测试用[不要选]</span>
<span class="langEN">For testing, don't choose</span>
</label>
</div>
<div style="font-size:13px;color:#aaa">
<div class="pd descAcmeURL descLetsEncrypt" style="display:none">
<a href="https://letsencrypt.org/" target="_blank">Let's Encrypt</a>:
<span class="langCN">请按照下面的操作步骤提示进行申请即可得到证书,证书有效期90天。</span>
<span class="langEN">Please follow the operation steps prompts below to apply, and you can get the certificate, which is valid for 90 days.</span>
</div>
<div class="pd descAcmeURL descZeroSSL" style="display:none">
<a href="https://zerossl.com/" target="_blank">ZeroSSL</a>:
<span style="color:#f80">
<span class="langCN">此URL可能需要先根据下面的提示进行操作来消除跨域不能访问的问题。</span>
<span class="langEN">This URL may need to be operated according to the prompts below to eliminate the problem of cross-domain inaccessibility.</span>
</span>
<span class="langCN">申请证书前,你需要根据ZeroSSL的<a href="https://zerossl.com/documentation/acme/" target="_blank">官方文档</a>,先注册ZeroSSL账号并生成一个EAB凭据,每次申请证书时使用此EAB凭据,按照下面的操作步骤提示进行申请即可得到证书,证书有效期90天。</span>
<span class="langEN">Before applying for a certificate, you need to follow ZeroSSL's <a href="https://zerossl.com/documentation/acme/" target="_blank">official documents</a>, register a ZeroSSL account and generate an EAB credential, and use this EAB credential every time you apply for a certificate, follow the operation steps prompts below to apply, and you can get the certificate, which is valid for 90 days.</span>
</div>
<div class="pd descAcmeURL descGoogle" style="display:none">
<a href="https://pki.goog/" target="_blank">Google Trust Services</a>:
<span style="color:#f80">
<span class="langCN">此URL可能需要先根据下面的提示进行操作来消除跨域不能访问的问题。</span>
<span class="langEN">This URL may need to be operated according to the prompts below to eliminate the problem of cross-domain inaccessibility.</span>
</span>
<span class="langCN">申请证书前,你需要根据Google的<a href="https://cloud.google.com/certificate-manager/docs/public-ca-tutorial" target="_blank">官方文档</a>,在Google Cloud中生成一个EAB凭据,每次申请证书时使用此EAB凭据,按照下面的操作步骤提示进行申请即可得到证书,证书有效期90天。</span>
<span class="langEN">Before applying for a certificate, you need to follow Google's <a href="https://cloud.google.com/certificate-manager/docs/public-ca-tutorial" target="_blank">official documents</a>, generate an EAB credential in Google Cloud, and use this EAB credential every time you apply for a certificate, follow the operation steps prompts below to apply, and you can get the certificate, which is valid for 90 days.</span>
<span style="color:#f80">
<span class="langCN">注意:因为同一个Google EAB凭据只能绑定到一个ACME账户(私钥),因此你在首次申请证书时,<span style="font-weight:bold;font-size:20px">必须同时保存好在第二步操作中新创建的或手动填写的ACME账户私钥</span>,下次申请证书时使用此EAB凭据必须和已保存的ACME账户私钥一起使用。</span>
<span class="langEN">Note: Because the same Google EAB credential can only be bound to one ACME account (Private key), when you apply for a certificate for the first time, <span style="font-weight:bold;font-size:20px">you must also save the newly generated or manually filled ACME account private key in the second step</span>, this EAB credential must be used together with the saved ACME account private key when applying for a certificate next time.</span>
</span>
</div>
</div>
<div class="pd FlexBox">
<div class="FlexItem">
<input class="in_acmeURL inputLang" style="width:100%"
placeholder-cn="请填写证书颁发机构ACME服务URL"
placeholder-en="Please fill in the Certificate Authority ACME Service URL">
</div>
<div style="padding-left:12px">
<span class="mainBtn mainBtnMin" onclick="acmeReadDirClick()" style="padding:0 50px">
<span class="langCN">读取服务目录</span>
<span class="langEN">Read service directory</span>
</span>
</div>
</div>
<div class="acmeReadDirState"></div>
<script>
//跨域支持的不好的ACME服务,直接复制源码到他们网站里面运行
var acmeReadDirGotoCORSInit=function(){
if(!window.IsReadDirGotoCORS)return;
var stateEl=$(".acmeReadDirGotoCORSState").show().html(`
<div style="color:#cb1d1d">
<span class="langCN">本客户端正在以跨域兼容模式运行,请按正常流程操作即可,目标ACME服务URL=${window.Default_ACME_URL}</span>
<span class="langEN">This client is running in cross-domain compatibility mode, please follow the normal process, the target ACME service URL=${window.Default_ACME_URL}</span>
</div>
`);
LangReview(stateEl);
};
var acmeReadDirGotoCORS=function(title){
"use strict";
var codes="// "+Lang("请复制本代码到打开的ACME服务URL页面的浏览器控制台中运行。","Please copy this code to the browser console of the opened ACME service URL page to run.",true)
+"\n\nvar Default_ACME_URL="+JSON.stringify(ACME.URL)+";"
+"\nvar IsReadDirGotoCORS=true;"
+"\nvar PageRawHTML=`"
+PageRawHTML.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"$\\{")
+"`;";
codes+="\nvar PageErrs="+JSON.stringify({
e0:Lang("运行失败,可能是此浏览器阻止了代码执行,请尝试换个浏览器。","Run failed, may be because the browser blocked the code execution, please try another browser.",true)
,e1:Lang("运行失败,解决办法:即将自动跳转到此站点的首页或404页,然后请再次粘贴代码运行","Run failed, solution: automatically jump to the homepage or 404 page of this site, then paste the code again to run",true)
})+";";
codes+="\n("+(function(){
console.clear();
try{
document.head.innerHTML=/<head[^>]*>([\S\s]+?)<\/head>/i.exec(PageRawHTML)[1];
document.body.innerHTML=/<body[^>]*>([\S\s]+)<\/body>/i.exec(PageRawHTML)[1];
var js=/<script[^>]*>([\S\s]+?)<\/script>/ig,m;
while(m=js.exec(PageRawHTML)) eval.call(window, m[1]);
ACME.Directory.toString(); //保证js已正确执行
}catch(e){ setTimeout(function(){ //部分浏览器json页面无法显示,跳转到根目录重试
console.error(e);
var url0=location.href, url=/^(.+\/\/[^\/\?#]+)/.exec(url0)[1];
if(url==url0 || url+"/"==url0) return console.error(PageErrs.e0);
console.log(PageErrs.e1); console.warn(PageErrs.e1); console.error(PageErrs.e1);
alert(PageErrs.e1); location.href=url;
}); }
}).toString()+")();\n";
$(".gotoCORSBox").hide();
var stateEl=$(".acmeReadDirState").append(`
<div class="gotoCORSBox" style="padding-top:15px">
<div class="pd Bold" style="color:red">
<i class="must">*</i>
`+(title||`
<span class="langCN">由于此ACME服务对跨域访问支持不良,</span>
<span class="langEN">Because this ACME service has poor support for cross-domain access, </span>
<span style="font-size:24px">
<span class="langCN">请按下面步骤操作:</span>
<span class="langEN">please follow the steps below:</span>
</span>`)+`
</div>
<div style="padding-left:40px">
<div class="pd">
<span class="langCN">1. 请在浏览器中直接打开此ACME服务URL,<a href="${ACME.URL}" target="_blank">点此打开</a>;</span>
<span class="langEN">1. Please open the ACME service URL directly in the browser, <a href="${ACME.URL}" target="_blank">click here to open</a>;</span>
</div>
<div class="pd">
<span class="langCN">2. 在上一步打开的页面中打开浏览器控制台(需等页面加载完成后,再按F12键);</span>
<span class="langEN">2. Open the browser console in the page opened in the previous step (after the page is loaded, press the F12 key);</span>
</div>
<div class="pd">
<span class="langCN">3. 复制以下代码,在第2步打开的浏览器控制台中运行,然后就可以正常申请证书了。</span>
<span class="langEN">3. Copy the following code, run it in the browser console opened in step 2, and then you can apply for the certificate normally.</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">工作原理:代码内包含了本页面源码,在目标页面内运行后将原样的显示出本客户端,然后按正常流程操作即可,此时已没有跨域问题了(既然打不过,那就加入他们)。</span>
<span class="langEN">Working principle: The code contains the source code of this page. After running in the target page, the client will be displayed as it is, and then operate according to the normal process. At this time, there is no cross-domain problem (if we can't beat them, we'd better join them).</span>
</div>
</div>
<div style="padding-top:20px">
<textarea class="gotoCORSText" style="width:100%;height:200px" readonly></textarea>
</div>
</div>
`);
$(".gotoCORSText").val(codes);
LangReview(stateEl);
};
</script>
</div>
</div>
<div class="mainBox">
<div class="pd itemTitle">
<span class="langCN">步骤二:证书配置</span>
<span class="langEN">Step 2: Certificate Configuration</span>
</div>
<div class="step2Hide step1Show">
<div class="itemBox" style="color:#999">
<span class="langCN">等待中,请先完成第一步...</span>
<span class="langEN">Waiting, please complete step 1 first...</span>
</div>
</div>
<div class="step1Hide step2Show">
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">温馨提示:如果上次申请过证书,可以拖拽已下载保存的记录LOG文件到本页面,将自动填充上次的配置信息。</span>
<span class="langEN">Reminder: If you have applied for a certificate last time, you can drag and drop the downloaded and saved record LOG file to this page, and the last configuration information will be automatically filled in.</span>
</div>
<div class="itemBox">
<div class="pd Bold">
<i class="must">*</i>
<span class="langCN">证书中要包含的域名:</span>
<span class="langEN">Domain name to be included in the certificate:</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">一个证书可以包含多个域名(支持通配符),比如填写:<i class="i">a.com, *.a.com, b.com, *.b.com</i>;第一个域名将作为证书的通用名称(Common Name);带通配符的域名只支持DNS验证,其他域名支持上传文件验证;注意:填了<i class="i">www.a.com</i>时,一般需要额外填上<i class="i">a.com</i>。</span>
<span class="langEN">A certificate can contain multiple domain names (wildcard are supported), for example, fill in: <i class="i">a.com, *.a.com, b.com, *.b.com</i>; the first domain name will be used as the Common Name of the certificate; Domain names with wildcard only support DNS verification, and other domain names support upload file verification ; Note: When <i class="i">www.a.com</i> is filled in, it is generally necessary to fill in <i class="i">a.com</i> additionally.</span>
</div>
<div class="FlexBox">
<div class="FlexItem">
<input class="in_domains inputLang" style="width:100%"
placeholder-cn="请填写你的域名,多个用逗号隔开"
placeholder-en="Please fill in your domain name, multiple separated by commas">
</div>
<div style="padding-left:15px;line-height:30px;font-size:13px;color:#aaa">
<label>
<input type="checkbox" class="choice_domains_store">
<span class="langCN">记住</span>
<span class="langEN">Remember</span>
</label>
</div>
</div>
</div>
<div class="itemBox">
<div class="pd Bold">
<i class="must">*</i>
<span class="langCN">证书的私钥:</span>
<span class="langEN">Private key of certificate:</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">生成或填写的私钥仅用于ACME接口签名,支持<i class="i">RSA(2048位+)</i>、<i class="i">ECC(<span class="eccCurveNames"></span>曲线)</i>私钥;<span style="color:#f80">注意:证书私钥的类型决定了申请到的证书是RSA证书还是ECC(ECDSA)证书,RSA类型适用性更广也更常见</span>;本客户端不会对此私钥进行保存或发送给其他任何人;证书签发后在部署到服务器时,需使用到此私钥;建议每次申请证书时均生成新的证书私钥。</span>
<span class="langEN">The generated or filled private key is only used for ACME interface signature, and supports <i class="i">RSA (2048-bit+)</i> and <i class="i">ECC (<span class="eccCurveNames"></span> curve)</i> private keys; <span style="color:#f80">Note: The type of certificate private key determines whether the applied certificate is an RSA certificate or a ECC(ECDSA) certificate, RSA type is more widely applicable and more common;</span> this client will not save or send this private key to anyone else; this private key needs to be used when deploying to the server after the certificate is issued; it is recommended to generate a new certificate private key every time you apply for a certificate.</span>
</div>
<div class="pd">
<label>
<input type="radio" name="choice_privateKey" value="generateRSA">
<span class="langCN">创建新RSA私钥</span>
<span class="langEN">Generate RSA private key</span>
</label>
<label>
<input type="radio" name="choice_privateKey" value="generateECC">
<span class="langCN">创建新ECC私钥</span>
<span class="langEN">Generate ECC private key</span>
</label>
<label>
<input type="radio" name="choice_privateKey" value="manual">
<span class="langCN">手动填写私钥</span>
<span class="langEN">Manually fill in the private key</span>
</label>
</div>
<div class="privateKeyBox">
<textarea class="in_privateKey inputLang" style="width:100%;height:60px"
placeholder-cn="请填写pem私钥,私钥文本以 -----BEGIN PRIVATE KEY----- 开头(这是PKCS#8格式,里面带有 RSA|EC 字符的PKCS#1格式也是支持的)"
placeholder-en="Please fill in the pem private key. The private key text starts with -----BEGIN PRIVATE KEY----- (this is in PKCS#8 format, and PKCS#1 format with RSA|EC characters in it is also supported)"></textarea>
</div>
<div class="privateKeyState"></div>
</div>
<div class="itemBox">
<div class="pd Bold">
<i class="must">*</i>
<span class="langCN">ACME账户的私钥:</span>
<span class="langEN">Private key of ACME account:</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">生成或填写的私钥仅用于ACME接口签名,支持<i class="i">RSA(2048位+)</i>、<i class="i">ECC(<span class="eccCurveNames"></span>曲线)</i>私钥;账户私钥类型对证书无影响;本客户端不会对此私钥进行保存或发送给其他任何人;一个私钥相当于一个账户,可用于吊销已签发的证书;建议每次申请证书时使用相同的一个私钥(这样短期内多次申请证书时,验证域名所有权的参数极有可能会保持相同),不过每次都生成一个新的私钥大部分情况下也不会有问题。</span>
<span class="langEN">The generated or filled private key is only used for ACME interface signature, and supports <i class="i">RSA (2048-bit+)</i> and <i class="i">ECC (<span class="eccCurveNames"></span> curve)</i> private keys; the account private key type has no effect on the certificate; this client will not save or send this private key to anyone else; A private key is equivalent to an account and can be used to revoke an issued certificate; it is recommended to use the same private key every time you apply for a certificate (in this way, the parameters used to verify the domain name ownership are likely to remain identical when multiple certificate applications are made in a short period of time); However, generating a new private key every time will not be a problem in most cases.</span>
<span class="eabShow" style="color:#f80">
<span class="langCN">注意:如果你选择的ACME服务(比如Google)要求提供EAB凭据并且限制了同一个EAB凭据只能绑定到一个ACME账户(私钥),那每次使用此EAB凭据时必须使用相同的一个私钥(首次时如果新创建了私钥,此新私钥需立即保存起来下次和此EAB凭据一起使用)。</span>
<span class="langEN">Note: If the ACME service you choose (such as Google) requires EAB credentials and limits the same EAB credentials to only one ACME account (private key), then you must use the same private key every time you use this EAB credential (if you generate a new private key for the first time, this new private key needs to be saved immediately and used with this EAB credential next time).</span>
</span>
</div>
<div class="pd">
<label>
<input type="radio" name="choice_accountKey" value="generateRSA">
<span class="langCN">创建新RSA私钥</span>
<span class="langEN">Generate RSA private key</span>
</label>
<label>
<input type="radio" name="choice_accountKey" value="generateECC">
<span class="langCN">创建新ECC私钥</span>
<span class="langEN">Generate ECC private key</span>
</label>
<label>
<input type="radio" name="choice_accountKey" value="manual">
<span class="langCN">手动填写私钥</span>
<span class="langEN">Manually fill in the private key</span>
</label>
</div>
<div class="accountKeyBox">
<textarea class="in_accountKey inputLang" style="width:100%;height:60px"
placeholder-cn="请填写pem私钥,私钥文本以 -----BEGIN PRIVATE KEY----- 开头(这是PKCS#8格式,里面带有 RSA|EC 字符的PKCS#1格式也是支持的)"
placeholder-en="Please fill in the pem private key. The private key text starts with -----BEGIN PRIVATE KEY----- (this is in PKCS#8 format, and PKCS#1 format with RSA|EC characters in it is also supported)"></textarea>
</div>
<div class="accountKeyState"></div>
</div>
<div class="itemBox">
<div class="pd Bold">
<i class="must">*</i>
<span class="langCN">ACME账户的联系邮箱:</span>
<span class="langEN">Contact email of ACME account:</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">此邮箱地址用于证书颁发机构给你发送邮件,比如:证书过期前的续期通知提醒。</span>
<span class="langEN">This email address is used by the certificate authority to send you emails, such as a reminder of renewal notice before the certificate expires.</span>
</div>
<div class="FlexBox">
<div class="FlexItem">
<input class="in_email inputLang" style="width:100%"
placeholder-cn="请填写一个你的邮箱"
placeholder-en="Please fill in one of your email addresses">
</div>
<div style="padding-left:15px;line-height:30px;font-size:13px;color:#aaa">
<label>
<input type="checkbox" class="choice_email_store">
<span class="langCN">记住</span>
<span class="langEN">Remember</span>
</label>
</div>
</div>
</div>
<div class="itemBox eabShow">
<div class="pd Bold">
<span class="langCN">EAB凭据:</span>
<span class="langEN">EAB Credentials:</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">当前ACME服务要求提供外部账号绑定凭据(External Account Binding),比如ZeroSSL:你可以在ZeroSSL的管理控制台的 Developer 中获得此凭据,所以你需要先注册一个ZeroSSL的账号。</span>
<span class="langEN">The current ACME service requires external account binding credentials, such as ZeroSSL: You can obtain this credentials in the Developer of the ZeroSSL management console, so you need to register a ZeroSSL account first.</span>
</div>
<div class="FlexBox" style="line-height:30px">
<div><i class="must">*</i>EAB KID:</div>
<div class="FlexItem" style="padding:0 50px 0 6px">
<input class="in_eab_kid inputLang" style="width:100%"
placeholder-cn="请填写EAB KID"
placeholder-en="Please fill in EAB KID">
</div>
<div style="padding:0 6px 0 0"><i class="must">*</i>HMAC KEY:</div>
<div class="FlexItem">
<input class="in_eab_key inputLang" style="width:100%"
placeholder-cn="请填写EAB HMAC KEY"
placeholder-en="Please fill in EAB HMAC KEY">
</div>
</div>
</div>
<div class="pd termsAgreeBox">
<label>
<input type="checkbox" class="choice_termsAgree">
<span class="termsAgreeTips"></span>
</label>
</div>
<div class="Center" style="padding:15px 0 10px">
<span class="mainBtn" onclick="configStepClick()" style="width:300px">
<span class="langCN">确定</span>
<span class="langEN">OK</span>
</span>
</div>
<div class="configStepState"></div>
</div>
</div>
<div class="mainBox">
<div class="pd itemTitle">
<span class="langCN">步骤三:验证域名所有权</span>
<span class="langEN">Step 3: Verify Domain Ownership</span>
</div>
<div class="step3Hide step2Show step1Show">
<div class="itemBox" style="color:#999">
<span class="langCN">等待中,请先完成第二步...</span>
<span class="langEN">Waiting, please complete step 2 first...</span>
</div>
</div>
<div class="step1Hide step2Hide step3Show">
<div class="pd" style="font-size:13px;color:#f80">
<span class="langCN">请给每个域名选择一个你合适的验证方式(推荐采用DNS验证,比较简单和通用),然后根据显示的提示完成对应的配置操作。</span>
<span class="langEN">Please select a suitable verification method for each domain name (DNS Verify is recommended, which is relatively simple and common), and then complete the corresponding configuration operations according to the displayed prompts.</span>
</div>
<div class="verifyBox"></div>
<script>
//显示所有域名的验证界面,html太多
var verifyBoxShow=function(){
"use strict";
var boxEl=$(".verifyBox").html("");
var auths=JSON.parse(JSON.stringify(ACME.StepData.auths));//避免改动原始数据
var domains=ACME.StepData.config.domains;
for(var i0=0;i0<domains.length;i0++){
var domain=domains[i0],auth=auths[domain]
var challs=auth.challenges;
for(var i=0;i<challs.length;i++){//排序,dns排前面
var o=challs[i];
o.challIdx=i;
o.name=ACME.ChallName(o);
o._sort=ACME.ChallSort(o);
}
challs.sort(function(a,b){return a._sort.localeCompare(b._sort)});
var choiceHtml="";
for(var i=0;i<challs.length;i++){
var chall=challs[i];
choiceHtml+=`
<label>
<input type="radio" name="choice_authItem_${i0}"
class="choice_authChall choice_authChall_${i0} choice_authChall_${i0}_${i}"
value="${i0}_${i}" challidx="${chall.challIdx}">${chall.name}
</label>
`;
}
boxEl.append(`
<div class="itemBox">
<div class="pd FlexBox" style="line-height:26px">
<div><i class="must">*</i></div>
<div style="width:180px;padding-right:5px;text-align:right;background:#03baed;color:#fff;border-radius: 4px;">${domain}</div>
<div class="FlexItem" style="padding-left:10px;">${choiceHtml}</div>
</div>
<div class="verifyItemBox_${i0}"></div>
<div class="verifyItemState_${i0}"></div>
</div>
`);
};
LangReview(boxEl);
$(".choice_authChall").bind("click",function(e){
var el=e.target,vals=el.value.split("_"),i0=+vals[0],i2=+vals[1];
var domain=domains[i0],auth=auths[domain],chall=auth.challenges[i2];
var html=['<div class="pd" style="padding-left:10px;font-size:13px;color:#aaa">'];
var nameCss='width:195px;text-align:right;padding-right:10px';
if(chall.type=="dns-01"){
html.push(Lang('请到你的域名DNS解析管理中,给下面这个子域名增加一条<i class="i">TXT记录</i>(一个子域名可以同时存在多条TXT记录,可以修改或删除老的记录)。','Please go to the DNS resolution management of your domain name and add a <i class="i">TXT record</i> for the following subdomain name (a subdomain name can have multiple TXT records at the same time, and the old records can be modified or deleted).')+'</div>');
html.push(`<div class="pd FlexBox">
<div style="${nameCss}">${Lang('子域名','Sub Domain')}:</div>
<div class="FlexItem">
<input style="width:100%" readonly value="_acme-challenge.${auth.identifier.value}" />
</div>
</div>
<div class="pd FlexBox">
<div style="${nameCss}">${Lang('TXT记录','TXT Record')}:</div>
<div class="FlexItem">
<input style="width:100%" readonly value="${chall.authTxtSHA256}" />
</div>
</div>`);
}else if(chall.type=="http-01"){
html.push(Lang('请在你的网站根目录中创建<i class="i">/.well-known/acme-challenge/</i>目录,目录内创建<i class="i">'+FormatText(chall.token)+'</i>文件,文件内保存下面的文件内容,保存好后<a href="http://'+auth.identifier.value+'/.well-known/acme-challenge/'+FormatText(chall.token)+'" target="_blank">请点此打开此文件URL</a>测试能否正常访问;注意:这个文件URL必须是80端口,并且公网可以访问,否则ACME无法访问到此地址将会验证失败。Windows操作提示:Windows中用<i class="i">.well-known.</i>作为文件夹名称就能创建<i class="i">.well-known</i>文件夹;IIS可能需在此文件夹下的MIME类型中给 <i class="i">.</i> (扩展名就是一个字".")添加 <i class="i">text/plain</i> 才能正常访问。','Please create the <i class="i">/.well-known/acme-challenge/</i> directory in the root directory of your website, create the <i class="i">'+FormatText(chall.token)+'</i> file in the directory, and save the following file content in the file; After saving, <a href="http://'+auth.identifier.value+'/.well-known/acme-challenge/'+FormatText(chall.token)+'" target="_blank">please click here to open the URL</a> of this file to test whether Normal access; note: the URL of this file must be 80 The port and the public network can be accessed, otherwise ACME cannot access this address and the verification will fail. Windows operation tips: In Windows, you can create a <i class="i">.well-known</i> folder by using <i class="i">.well-known.</i> as the folder name; IIS may need to give <i class="i">.</i> in the MIME type under this folder (the extension is a word ".") Add <i class="i">text/plain</i> for normal access.')+'</div>');
html.push(`<div class="pd FlexBox">
<div style="${nameCss}">${Lang('文件URL','File URL')}:</div>
<div class="FlexItem">
<input style="width:100%" readonly value="http://${auth.identifier.value}/.well-known/acme-challenge/${FormatText(chall.token)}" />
</div>
</div>
<div class="pd FlexBox">
<div style="${nameCss}">${Lang('文件内容','File Content')}:</div>
<div class="FlexItem">
<input style="width:100%" readonly value="${chall.authTxt}" />
</div>
</div>`);
}else{
html.push(Lang('非预定义验证类型,请使用<i class="i">Key Authorizations (Token+.+指纹)</i>自行处理,<i class="i">Digest</i>为Key Authorizations的SHA-256 Base64值。','For non-predefined authentication types, please use <i class="i">Key Authorizations (Token+.+Thumbprint)</i> to handle it yourself. <i class="i">Digest</i> is the SHA-256 Base64 value of Key Authorizations.')+'</div>');
html.push(`<div class="pd FlexBox">
<div style="${nameCss}">Key Authorizations:</div>
<div class="FlexItem">
<input style="width:100%" readonly value="${chall.authTxt}" />
</div>
</div>
<div class="pd FlexBox">
<div style="${nameCss}">Digest(SHA-256 Base64):</div>
<div class="FlexItem">
<input style="width:100%" readonly value="${chall.authTxtSHA256Base64}" />
</div>
</div>`);
}
$(".verifyItemBox_"+i0).html(html.join('\n'));
});
for(var i0=0;i0<domains.length;i0++){
var el=$(".choice_authChall_"+i0+"_0");
el[0]&&el[0].click(); //默认选中每个域名的第一个
}
};
</script>
<div class="itemBox">
<div class="pd" style="font-size:15px">
<span class="langCN">请每个域名选择好对应的验证方式,根据显示的提示进行对应的配置操作;<span style="color:#cb1d1d">必须所有域名配置完成后,再来点击下面的“开始验证”按钮进行验证,</span>如果验证失败,需要返回第二步重新开始操作。</span>
<span class="langEN">Please select the corresponding verify method for each domain name, and perform the corresponding configuration operation according to the displayed prompts; <span style="color:#cb1d1d">after all domain names are configured, click the "Start Verify" button below to verify,</span> if the verify fails, you need to go back to the step 2 Start the operation.</span>
</div>
<div class="Center" style="padding:15px 0 10px">
<span class="mainBtn verifyStepBtn" onclick="verifyStepClick()" style="width:300px">
<span class="langCN">开始验证</span>
<span class="langEN">Start Verify</span>
</span>
<span class="mainBtn verifyRunStopBtn" onclick="verifyRunStopClick()" style="width:300px;background:#aaa">
<span class="langCN">取消</span>
<span class="langEN">Cancel</span>
</span>
<span class="mainBtn finalizeOrderBtn" onclick="finalizeOrderClick()" style="width:300px">
<span class="langCN">重试</span>
<span class="langEN">Retry</span>
</span>
</div>
<div class="verifyStepState"></div>
</div>
</div>
</div>
<div class="mainBox">
<div class="pd itemTitle">
<span class="langCN">步骤四:下载保存证书PEM文件</span>
<span class="langEN">Step 4: Download and save the certificate PEM file</span>
</div>
<div class="step4Hide step3Show step2Show step1Show">
<div class="itemBox" style="color:#999">
<span class="langCN">等待中,请先完成第三步...</span>
<span class="langEN">Waiting, please complete step 3 first...</span>
</div>
</div>
<div class="step1Hide step2Hide step3Hide step4Show">
<div class="itemBox">
<div class="pd Bold">
<i class="must">*</i>
<span class="langCN">保存证书PEM文件:</span>
<span class="langEN">Save certificate PEM file: </span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN"><span style="color:#f80">必须保存此文件,</span>请点击下载按钮下载,或者将证书文本内容复制保存为<i class="i downloadCertFileName"></i>文件(PEM纯文本格式);文件名后缀可改成 <i class="i">.crt</i> 或 <i class="i">.cer</i>,这样在Windows中能直接双击打开查看。本PEM格式文件已包含你的域名证书、和完整证书链,文本中第一个CERTIFICATE为你的域名证书,后面的为证书颁发机构的中间证书和根证书,如过有需要你可以自行拆分成多个.pem文件。</span>
<span class="langEN"><span style="color:#f80">This file must be saved,</span> please click the download button to download, or copy the text content of the certificate and save it as <i class="i downloadCertFileName"></i> file (PEM plain text format); the file name suffix can be changed to <i class="i">.crt </i> or <i class="i">.cer </i>, so that it can be directly double-clicked to open and view in Windows. This PEM format file already contains your domain name certificate and complete certificate chain. The first CERTIFICATE in the text is your domain name certificate, followed by the intermediate certificate and root certificate of the certificate authority, if necessary, you can split it into multiple .pem files.</span>
</div>
<div class="FlexBox">
<div class="FlexItem">
<textarea class="txt_downloadCert" style="width:100%;height:160px" readonly></textarea>
</div>
<div style="padding-left:10px;line-height:30px;font-size:13px;color:#aaa">
<div class="mainBtn" onclick="downloadBtnClick('Cert')">
<span class="langCN">下载保存</span>
<span class="langEN">Download</span>
</div>
</div>
</div>
</div>
<div class="itemBox">
<div class="pd Bold">
<i class="must">*</i>
<span class="langCN">保存证书私钥KEY文件:</span>
<span class="langEN">Save the certificate private key KEY file: </span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">请点击下载按钮下载,或者将私钥文本内容复制保存为<i class="i downloadKeyFileName"></i>文件(PEM纯文本格式,.key后缀可自行修改成.pem)。如果第二步操作中你手动填写了证书私钥,此处的证书私钥和你填写的是完全一样的,可以不需要重复保存;<span style="color:#f80">如果你是新创建的证书私钥,则你必须下载保存此证书私钥文件。</span></span>
<span class="langEN">Please click the download button to download, or copy and save the text content of the private key as <i class="i downloadKeyFileName"></i> file (PEM plain text format, the .key suffix can be modified to .pem by yourself). If you manually filled in the certificate private key in the step 2, the certificate private key here is exactly the same as what you filled in, and you don’t need to save it repeatedly; <span style="color:#f80">if you are a newly created certificate private key, you must download and save it This certificate private key file.</span></span>
</div>
<div class="FlexBox">
<div class="FlexItem">
<textarea class="txt_downloadKey" style="width:100%;height:80px" readonly></textarea>
</div>
<div style="padding-left:10px;line-height:30px;font-size:13px;color:#aaa">
<div class="mainBtn" onclick="downloadBtnClick('Key')">
<span class="langCN">下载保存</span>
<span class="langEN">Download</span>
</div>
</div>
</div>
</div>
<div class="itemBox">
<div class="pd Bold">
<i class="must">*</i>
<span class="langCN">保存记录LOG文件:</span>
<span class="langEN">Save the record LOG file: </span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">建议下载保存此文件,本记录文件包含了所有数据,包括:证书PEM文本、证书私钥PEM文本、账户私钥PEM文本、所有配置参数。下次你需要续签新证书时,可以将本记录文件直接拖拽进本页面,会自动填写所有参数。</span>
<span class="langEN">It is recommended to download and save this file. This record file contains all data, including: certificate PEM text, certificate private key PEM text, account private key PEM text, and all configuration parameters. Next time you need to renew a new certificate, you can drag and drop the record file directly into this page, and all parameters will be filled in automatically.</span>
</div>
<div class="FlexBox">
<div class="FlexItem">
<textarea class="txt_downloadLog" style="width:100%;height:80px" readonly></textarea>
</div>
<div style="padding-left:10px;line-height:30px;font-size:13px;color:#aaa">
<div class="mainBtn" onclick="downloadBtnClick('Log')">
<span class="langCN">下载保存</span>
<span class="langEN">Download</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="mainBox">
<div class="itemBox">
<div class="pd Bold">
<span class="langCN">你需要其他格式的证书文件?</span>
<span class="langEN">Do you need certificate files in other formats?</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">大部分服务器程序支持直接使用 <i class="i downloadCertFileName"></i>+<i class="i downloadKeyFileName"></i> 来配置开启HTTPS(比如Nginx),如果你需要 <i class="i">*.pfx</i>、<i class="i">*.p12</i> 格式的证书(比如用于IIS),请用下面命令将PEM证书转换成 <i class="i">pfx/p12</i> 格式:</span>
<span class="langEN">Most server programs support directly using <i class="i downloadCertFileName"></i>+<i class="i downloadKeyFileName"></i> to configure and enable HTTPS (such as Nginx). If you need a certificate in <i class="i">*.pfx</i> or <i class="i">*.p12</i> format (such as for IIS), please use the following command to convert the PEM certificate Convert to <i class="i">pfx/p12</i> format:</span>
</div>
<div class="code">openssl pkcs12 -export -out <span class="downloadFileName"></span>.pfx -inkey <span class="downloadKeyFileName"></span> -in <span class="downloadCertFileName"></span></div>
</div>
<div class="itemBox">
<div class="pd Bold">
<span class="langCN">IIS证书链缺失?</span>
<span class="langEN">IIS certificate chain missing?</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">对于Windows IIS服务器,你需要将证书链安装到“本地计算机”的“中间证书颁发机构”中;请将PEM证书中的所有证书拆分成单个PEM文件(后缀改成<i class="i">.crt</i>或<i class="i">.cer</i>),然后将系统中缺失的中间证书双击打开然后安装进去;详细参考:</span>
<span class="langEN">For Windows IIS server, you need to install the certificate chain into "Intermediate Certification Authorities" in "Local Computer"; please split all certificates in PEM certificate into a single PEM file (change the suffix to <i class="i">.crt</i> or <i class="i">.cer</i>), then double-click to open the missing intermediate certificate in the system Then install it; detailed reference:</span>
<a href="http://support.microsoft.com/kb/954755" target="_blank">http://support.microsoft.com/kb/954755</a>
</div>
</div>
<div class="itemBox">
<div class="pd Bold">
<span class="langCN">本客户端部分原理简介</span>
<span class="langEN">Introduction to the principle of this client</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">得益于现代浏览器的 <a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto" target="_blank">crypto.subtle</a> 对加密功能标准化,不依赖其他任何js库就能在网页上实现 <i class="i">RSA</i>、<i class="i">ECC</i> 的加密、解密、签名、验证、和密钥对生成。在本客户端内的 <i class="i">X509</i> 对象中:用 X509.CreateCSR 来生成CSR,用 X509.KeyGenerate 来创建PEM格式密钥,用 X509.KeyParse 来解析PEM格式密钥,用 X509.KeyExport 来导出PEM格式密钥;这些功能都是根据相应的标准用js代码在二进制层面上实现的,二进制数据操作封装在了 <i class="i">ASN1</i> 对象中:实现了 ASN.1 标准的二进制解析和封包,使用 ASN1.ParsePEM 方法可以解析任意的PEM格式密钥或证书。以上这些都是实现ACME网页客户端的核心基础。</span>
<span class="langEN">Thanks to the standardization of encryption functions by <a href="https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto" target="_blank">crypto.subtle</a> of modern browsers, <i class="i">RSA</i> and <i class="i">ECC</i> encryption, decryption, signature, verification, and key pair generation can be implemented on web pages without relying on any other js library. In the <i class="i">X509</i> object in this client: use X509.CreateCSR to generate CSR, use X509.KeyGenerate to create PEM format key, use X509.KeyParse to parse PEM format key, use X509.KeyExport to export PEM format key; These functions are implemented at the binary level with js code according to the corresponding standards, and binary data operations are encapsulated in <i class="i">ASN1</i> objects: ASN.1 standard binary parsing and encapsulation are implemented, Arbitrary PEM format keys or certificates can be parsed using the ASN1.ParsePEM method. These are the core foundations for implementing the ACME web client.</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">然后就是对接ACME实现证书的签发,和实现交互UI;对接ACME可以直接参考 RFC 8555 标准。有些证书颁发机构的ACME服务对浏览器支持不良,未提供齐全的 <i class="i">Access-Control-*</i> 响应头,导致网页内无法直接调用服务接口;目前采用的解决办法非常简单粗暴,比如ZeroSSL:检测到此ACME服务存在跨域问题时,会调用 <i class="i">acmeReadDirGotoCORS()</i> 方法告诉用户操作步骤(你可以<a onclick="acmeReadDirGotoCORS();alert('调用成功,请到第一步操作')">点此</a>手动调用此方法),通过在他们的页面内运行本客户端来消除跨域问题(既然打不过,那就加入他们)。</span>
<span class="langEN">Then it is to connect with ACME to realize certificate issuance and realize interactive UI; for connecting with ACME, you can directly refer to the RFC 8555 standard. The ACME services of some certificate authorities do not support browsers well, and do not provide complete <i class="i">Access-Control-*</i> response headers, so that the service interface cannot be called directly in the web page; the current solution is very simple and rude, such as ZeroSSL: detect this ACME When there is a cross-domain problem with the service, the <i class="i">acmeReadDirGotoCORS()</i> method will be called to tell the user the operation steps (you can call this method manually by <a onclick="acmeReadDirGotoCORS();alert('Call succeeded, please go to step 1')">clicking here</a>), and the cross-domain problem will be eliminated by running this client in their page (if we can't beat them, we'd better join them).</span>
</div>
</div>
<div class="itemBox">
<div class="pd Bold">
<span class="langCN">QQ群:交流与支持</span>
<span class="langEN">QQ group: communication and support</span>
</div>
<div class="pd" style="font-size:13px;color:#aaa">
<span class="langCN">欢迎加QQ群:<i class="i">421882406</i>,纯小写口令:<i class="i">xiangyuecn</i>。如需功能定制,网站、App、小程序、前端和后端等开发需求,请加此QQ群,联系群主(即作者),谢谢~</span>
<span class="langEN">Welcome to join the QQ group: <i class="i">421882406</i> , code: <i class="i">xiangyuecn</i> . If you need function customization, website, app, applet, front-end and back-end development needs, please join this QQ group and contact the group owner (ie the author), thank you~</span>
</div>
</div>
</div>
<div style="padding-top:20px;font-size:13px;color:#aaa">
<div class="pd langEN">The Chinese-English translation is mainly from: Chrome comes with translation + Baidu translation, which is translated from Chinese to English.</div>
<div class="pd">
<span class="versionBox"></span>
<a style="margin-left:15px" href="https://github.com/xiangyuecn/ACME-HTML-Web-Browser-Client/blob/main/LICENSE" target="_blank">License: GPL-3.0</a>
</div>
</div>
<div class="toastState" style="display:none;position:fixed;padding:10px;bottom:10px;right:10px;width:360px;max-height:120px;overflow-y:auto;background:#fff;box-shadow: 0px 0px 3px #aaa;border-radius: 10px;"></div>
<div class="donateWidget" style="position:fixed;top:30%;right:5px;width:160px">
<div style="border-radius:12px;background:linear-gradient(160deg, rgba(0,179,255,.7) 20%, rgba(177,0,255,.7) 80%);max-width:300px;padding:20px 10px;text-align: center;">
<div style="font-size:18px;color:#fff;">
<span class="langCN">赏包辣条?</span>
<span class="langEN">Donate a Coke?</span>
</div>
<div style="font-size:14px;color:#fff;">
<div class="langCN" style="padding:10px 0">客户端工具开发维护不易,期望本项目对你能有所帮助,欢迎通过下面按钮打赏作者~</div>
<span class="langEN">It is not easy to develop and maintain client tools. I hope this project can help you. Welcome to reward the author through the following buttons~</span>
</div>
<div>
<span class="langCN">
<a id="id_ek8v" target="_blank" class="mainBtn mainBtnMin" style="color:#fff">打赏 <span class="donateBtnIco"></span></a>
<script> id_ek8v.href=/gitee\.io/.test(location.host)?"https://xiangyuecn.gitee.io/docs/about.html":"https://xiangyuecn.github.io/Docs/about.html" </script>
</span>
<span class="langEN">
<a href="https://xiangyuecn.github.io/Docs/about.html" target="_blank" class="mainBtn mainBtnMin" style="color:#fff">Donate <span class="donateBtnIco"></span></a>
</span>
</div>
</div>
</div>
<div class="langBtnBox" style="position:fixed;top:0;right:0;padding:5px 10px;font-size:14px;border-radius:0 0 0 10px;background:#f5f5f5;">
Language:
<a class="langBtn langBtn_cn" onclick="LangClick('cn')">中文</a>
| <a class="langBtn langBtn_en" onclick="LangClick('en')">EN</a>
</div>
</div>
<style>
body{
word-wrap: break-word;
--word-break: break-all;
background:#f5f5f5 center top no-repeat;
background-size: auto 680px;
}
pre{
white-space:pre-wrap;
}
label,label *{
cursor: pointer;
}
label:hover{
color:#06c;
}
a{
text-decoration: none;
color:#06c;
cursor: pointer;
}
a:hover{
color:#f00;
}
input, textarea {
--outline: 0;
border: 1px solid #999;
padding: 2px;
box-sizing: border-box;
font-size: 15px;
line-height:24px;
}
.main{
max-width:900px;
margin:0 auto;
padding-bottom:80px
}
.mainBox{
margin-top:12px;
padding: 12px;
border-radius: 6px;
background: #fff;
box-shadow: 2px 2px 3px #aaa;
}
.mainBtn{
display: inline-block;
cursor: pointer;
border: none;
border-radius: 3px;
background: #f80;
color:#fff;
padding: 0 15px;
line-height: 36px;
height: 36px;
overflow: hidden;
vertical-align: middle;
}
.mainBtnMin{
height: 30px;
line-height: 30px;
font-size: 14px;
padding: 0 12px;
}
.mainBtn:hover{
opacity:0.8;
}
.mainBtn:active{
opacity:1;
background: #f00;
}
.pd{
padding:0 0 8px 0;
}
.pdT{
padding:8px 0 0 0;
}
.lb{
display:inline-block;
vertical-align: middle;
background:#00940e;
color:#fff;
font-size:14px;
padding:2px 8px;
border-radius: 99px;
}
.Fill {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.Center{
text-align: center;
}
.CenterV {
display: -webkit-flex;
display: -ms-flex;
display: -moz-flex;
display: flex;
-webkit-align-items: center;
-ms-align-items: center;
-moz-align-items: center;
align-items: center;
}
.FlexBox {
display: -webkit-flex;
display: -ms-flex;
display: -moz-flex;
display: flex;
}
.FlexBoxV{
-webkit-flex-direction:column;
-ms-flex-direction:column;
-moz-flex-direction:column;
flex-direction:column;
}
.FlexCenter{
-webkit-box-pack:center;
-ms-box-pack:center;
-moz-box-pack:center;
box-pack:center;
-webkit-justify-content:center;
-ms-justify-content:center;
-moz-justify-content:center;
justify-content:center;
}
.FlexCenterV{
-webkit-box-align:center;
-ms-box-align:center;
-moz-box-align:center;
box-align:center;
-webkit-align-items:center;
-ms-align-items:center;
-moz-align-items:center;
align-items:center;
}
.FlexItem {
-webkit-flex: 1;
-ms-flex: 1;
-moz-flex: 1;
flex: 1;
}
.Bold{
font-weight: bold;
}
.code{
padding: 15px;
background-color: #000;
vertical-align: middle;
color: #fff;
font-size: 14px;
white-space: pre-wrap;
border-radius: 6px;
font-style: normal;
}
.i{
padding: 2px 4px;
background-color: #f6f6f6;
vertical-align: top;
color: #c7254e;
font-size: 12px;
white-space: pre-wrap;
border-radius: 4px;
font-style: normal;
}
i.must{
color:red;
font-style:normal;
}
.itemTitle{
font-size: 24px;
font-weight: bold;
color: #03baed;
}
.itemBox{
padding:8px;
margin-bottom:6px;
border:1px #ccc dashed;
border-radius: 6px;
}
</style>
<script>
//=================================================
//================= UI functions ==================
//=================================================
//LICENSE: GPL-3.0, https://github.com/xiangyuecn/ACME-HTML-Web-Browser-Client
(function(){
"use strict";
var ChoiceAcmeURLStoreKey="ACME_HTML_choice_acmeURL";
var InputDomainsStoreKey="ACME_HTML_input_domains";
var InputEmailStoreKey="ACME_HTML_input_email";
var DropConfigFile={}; //拖拽进来的上次配置文件
/************** UI: Initialize on Launch **************/
window.initMainUI=function(){
$(".eccCurveNames").html(X509.SupportECCType2Names().join(Lang("、",", ")));
$(".donateBtnIco").html(unescape("%uD83D%uDE18"));
$(".versionBox").html(Lang("版本: "+Version,"Ver: "+Version));