Files
toolbox/plugin/dev/cert_convert/index.html
T
2023-11-24 22:45:30 +08:00

327 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{extend name="common/plugin_layout" /}
{block name="title"}{$plugin.title} - {:config_get('title')}{/block}
{block name="main"}
<div class="container-xl" id="app">
<div class="col-sm-12 col-md-10 col-xl-8 center-block">
<div class="card card-preview">
<div class="card-inner mt-3">
<div class="nya-title nk-ibx-action-item progress-rating">
<span class="nk-menu-text font-weight-bold">RSA证书格式转换</span>
</div>
<div class="d-flex flex-wrap">
<div class="form-group flex-fill mr-2">
<label class="form-label">从格式 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<select class="form-control" v-model="input.from">
<option value="">请选择</option>
<option v-for="value in convert_from" :value="value">{{value}}</option>
</select>
</div>
</div>
<div class="form-group flex-fill">
<label class="form-label">转换至 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<select class="form-control" v-model="input.to">
<option value="">请选择</option>
<option v-for="value in convert_to" :value="value">{{value}}</option>
</select>
</div>
</div>
</div>
<div class="form-group" v-show="input.from=='PEM'&&input.to!='DER'&&input.to!='PKCS7'">
<label class="form-label" for="customFileLabel">PEM 私钥文件 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile1" accept=".pem,.key" required @change="handleFile('pem_private', event)">
<label class="custom-file-label" for="customFile1">点击选择文件</label>
</div>
</div>
</div>
<div class="form-group" v-show="input.from=='PEM'&&input.to!='DER'">
<label class="form-label" for="customFileLabel">PEM 服务器证书文件 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile2" accept=".pem,.crt,.cer" required @change="handleFile('pem_mycert', event)">
<label class="custom-file-label" for="customFile2">点击选择文件</label>
</div>
</div>
</div>
<div class="form-group" v-show="input.from=='PEM'&&input.to!='DER'">
<label class="form-label" for="customFileLabel">PEM 中间/根证书文件</label>
<div class="form-control-wrap">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile3" accept=".pem,.crt,.cer" @change="handleFile('pem_cacert', event)">
<label class="custom-file-label" for="customFile3">点击选择文件(可选)</label>
</div>
</div>
</div>
<div class="form-group" v-show="input.from=='PEM'&&input.to=='PKCS12'">
<label class="form-label">PKCS12 证书密码</label>
<div class="form-control-wrap">
<input type="text" v-model="input.pkcs12_pass" placeholder="密码可为空" class="form-control">
</div>
</div>
<div class="form-group" v-show="input.from=='PEM'&&input.to=='JKS'">
<label class="form-label">JKS 证书密码 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<input type="text" v-model="input.jks_pass" placeholder="" class="form-control" required>
</div>
</div>
<div class="form-group" v-show="input.from=='PKCS12'">
<label class="form-label" for="customFileLabel">PKCS12 证书文件 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile4" accept=".pfx,.p12" required @change="handleFile('pkcs12_cert', event)">
<label class="custom-file-label" for="customFile4">点击选择文件(支持pfx、p12</label>
</div>
</div>
</div>
<div class="d-flex flex-wrap" v-if="input.from=='PKCS12'">
<div class="form-group flex-fill mr-2">
<label class="form-label">原PKCS12证书密码</label>
<div class="form-control-wrap">
<input type="text" v-model="input.pkcs12_pass" placeholder="没有密码请留空" class="form-control">
</div>
</div>
<div class="form-group flex-fill" v-show="input.to=='JKS'">
<label class="form-label">新JKS证书密码 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<input type="text" v-model="input.jks_pass" placeholder="填写JKS证书密码" class="form-control" required>
</div>
</div>
</div>
<div class="form-group" v-show="input.from=='JKS'">
<label class="form-label" for="customFileLabel">JKS 证书文件 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile5" accept=".jks,.ks,.keystore" required @change="handleFile('jks_cert', event)">
<label class="custom-file-label" for="customFile5">点击选择文件(支持jks、ks、keystore</label>
</div>
</div>
</div>
<div class="d-flex flex-wrap" v-if="input.from=='JKS'">
<div class="form-group flex-fill">
<label class="form-label">原JKS证书密码 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<input type="text" v-model="input.jks_pass" placeholder="填写JKS证书密码" class="form-control" required>
</div>
</div>
<div class="form-group flex-fill ml-2" v-show="input.to=='PKCS12'">
<label class="form-label">新PKCS12证书密码</label>
<div class="form-control-wrap">
<input type="text" v-model="input.pkcs12_pass" placeholder="留空则与原密码相同" class="form-control">
</div>
</div>
</div>
<div class="form-group" v-show="input.from=='PEM'&&input.to=='DER'">
<label class="form-label" for="customFileLabel">PEM 证书文件 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile6" accept=".pem,.crt,.cer" required @change="handleFile('pem_cert', event)">
<label class="custom-file-label" for="customFile6">点击选择文件</label>
</div>
</div>
</div>
<div class="form-group" v-show="input.from=='DER'">
<label class="form-label" for="customFileLabel">DER 证书文件 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile7" accept=".der,.crt,.cer" required @change="handleFile('der_cert', event)">
<label class="custom-file-label" for="customFile7">点击选择文件</label>
</div>
</div>
</div>
<div class="form-group" v-show="input.from=='PKCS7'">
<label class="form-label" for="customFileLabel">PKCS7 证书文件 <span class="text-danger">*</span></label>
<div class="form-control-wrap">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile8" accept=".p7b,.p7c,.spc" required @change="handleFile('pkcs7_cert', event)">
<label class="custom-file-label" for="customFile8">点击选择文件(支持p7b、p7c、spc)</label>
</div>
</div>
</div>
<button class="btn btn-dim btn-outline-secondary btn-block card-link mb-3" @click="submit">
开始转换
</button>
</div>
</div>
<div class="card card-preview" v-show="show_result" style="display:none">
<div class="card-inner mt-3">
<div class="nya-title nk-ibx-action-item progress-rating">
<span class="nk-menu-text font-weight-bold">转换结果</span>
</div>
<ul class="list-group">
<li class="list-group-item" v-for="(item,index) in result_file"><b>{{item.name}}</b><a href="javascript:" @click="download(index)"><em class="icon ni ni-download"></em>点击下载</a></li>
</ul>
</div>
</div>
<div class="card card-preview">
<div class="card-inner">
<h6><em class="icon ni ni-info"></em> 工具说明</h6>
<div class="accordion-inner">
<p>本工具支持PEM、DER、PKCS12、PKCS7、JKS等格式的证书转换</p>
<p><b>证书格式介绍</b></p>
<p><b>PEM</b>以base64的形式存放证书、私钥,常见后缀是.pem .crt .cer .key</p>
<p><b>DER</b>以二进制的形式存放证书、私钥,常见后缀是.der .crt .cer</p>
<p><b>PKCS#12</b>以二进制的形式存放证书+私钥,通常包含保护密码,常见后缀是.pfx .p12</p>
<p><b>PKCS#7</b>以树状展示证书链,也支持单个证书,不含私钥,常见后缀是.p7b .p7c .spc</p>
<p><b>JKS</b>是Java平台使用的证书存储库文件,存放证书+私钥,有密码保护,常见后缀是.jks .ks .keystore</p>
</div>
</div>
</div>
</div>
</div>
{/block}
{block name="script"}
<script src="{$cdn_cdnjs}vue/2.6.14/vue.min.js"></script>
<script src="{$cdn_cdnjs}FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
mode: 0,
convert_from: [
'PEM',
'DER',
'PKCS12',
'PKCS7',
'JKS',
],
convert_to: [
],
input: {
from:'',
to:'',
pem_private: null,
pem_mycert: null,
pem_cacert: null,
pkcs12_pass: '',
jks_pass: '',
pkcs12_cert: null,
jks_cert: null,
pem_cert: null,
der_cert: null,
pkcs7_cert: null,
},
show_result: false,
result_file: [
]
},
watch: {
"input.from"(newVal) {
if(newVal == 'PEM'){
this.convert_to = ['PKCS12','PKCS7','DER','JKS'];
}else if(newVal == 'PKCS12'){
this.convert_to = ['PEM','JKS'];
}else if(newVal == 'JKS'){
this.convert_to = ['PEM','PKCS12'];
}else if(newVal == 'DER'){
this.convert_to = ['PEM'];
}else if(newVal == 'PKCS7'){
this.convert_to = ['PEM'];
}else{
this.convert_to = [];
}
this.input.to = ''
}
},
methods: {
handleFile(name, event) {
this.input[name] = event.target.files[0];
},
submit() {
if(this.input.from == ''){
layer.alert('转换源格式不能为空');return;
}
if(this.input.to == ''){
layer.alert('转换目标格式不能为空');return;
}
var data = new FormData();
data.append('from', this.input.from);
data.append('to', this.input.to);
if(this.input.from == 'PEM' && this.input.to != 'DER'){
if(this.input.to != 'PKCS7'){
if(this.input.pem_private == null){layer.alert('PEM私钥不能为空');return;}
data.append('private', this.input.pem_private);
}
if(this.input.pem_mycert == null){layer.alert('PEM服务器证书不能为空');return;}
data.append('cert', this.input.pem_mycert);
data.append('cacert', this.input.pem_cacert);
if(this.input.to == 'PKCS12'){
data.append('pass', this.input.pkcs12_pass);
}else if(this.input.to == 'JKS'){
if(this.input.jks_pass == ''){layer.alert('JKS证书密码不能为空');return;}
data.append('pass', this.input.jks_pass);
}
}else if(this.input.from == 'PEM' && this.input.to == 'DER'){
if(this.input.pem_cert == null){layer.alert('PEM证书不能为空');return;}
data.append('cert', this.input.pem_cert);
}else if(this.input.from == 'DER' && this.input.to == 'PEM'){
if(this.input.der_cert == null){layer.alert('DER证书不能为空');return;}
data.append('cert', this.input.der_cert);
}else if(this.input.from == 'PKCS12'){
if(this.input.pkcs12_cert == null){layer.alert('PKCS12证书文件不能为空');return;}
data.append('cert', this.input.pkcs12_cert);
if(this.input.to == 'PEM'){
data.append('pass', this.input.pkcs12_pass);
}else if(this.input.to == 'JKS'){
if(this.input.jks_pass == ''){layer.alert('新JKS证书密码不能为空');return;}
data.append('srcpass', this.input.pkcs12_pass);
data.append('destpass', this.input.jks_pass);
}
}else if(this.input.from == 'JKS'){
if(this.input.jks_cert == null){layer.alert('JKS证书文件不能为空');return;}
data.append('cert', this.input.jks_cert);
if(this.input.to == 'PEM'){
data.append('pass', this.input.jks_pass);
}else if(this.input.to == 'PKCS12'){
if(this.input.jks_pass == ''){layer.alert('原JKS证书密码不能为空');return;}
data.append('srcpass', this.input.jks_pass);
data.append('destpass', this.input.pkcs12_pass);
}
}else if(this.input.from == 'PKCS7' && this.input.to == 'PEM'){
if(this.input.pkcs7_cert == null){layer.alert('PKCS7证书不能为空');return;}
data.append('cert', this.input.pkcs7_cert);
}
this.show_result = false;
var ii = layer.load();
var that = this;
$.ajax({
type : "POST",
url : "/api/{$plugin.alias}/convert",
data : data,
processData: false,
contentType: false,
dataType : 'json',
success : function(data) {
layer.close(ii);
if(data.status == 'ok'){
that.result_file = data.data.files;
that.show_result = true;
}else{
layer.alert(data.message, {icon: 7});
}
},
error : function(){
layer.close(ii);
layer.msg('服务器错误', {icon: 5});
}
});
},
download(index) {
var file_info = this.result_file[index]
if(!file_info) return;
var byteCharacters = window.atob(file_info.data)
var byteNumbers = new Array(byteCharacters.length)
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i)
}
var byteArray = new Uint8Array(byteNumbers)
var blob = new Blob([byteArray], {type: "application/force-download"});
saveAs(blob, file_info.file);
}
},
})
</script>
{/block}