提交 www
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
# UKey 读写工具
|
||||
【2023年12月1日】
|
||||
从 mainkey 文件生成三个 ukey
|
||||
|
||||
【2023年12月15日】
|
||||
把三个 ukey 内的主密钥生成 mainkey 文件
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,65 @@
|
||||
function stringToHex(str){
|
||||
var val = "";
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
var v = str.charCodeAt(i).toString(16);
|
||||
if ( v.length < 2 ) {
|
||||
v = "0" + v;
|
||||
}
|
||||
val += v;
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
|
||||
function hexToStr(hex,encoding) {
|
||||
var trimedStr = hex.trim();
|
||||
var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
|
||||
var len = rawStr.length;
|
||||
if (len % 2 !== 0) {
|
||||
alert("Illegal Format ASCII Code!");
|
||||
return "";
|
||||
}
|
||||
var curCharCode;
|
||||
var resultStr = [];
|
||||
for (var i = 0; i < len; i = i + 2) {
|
||||
curCharCode = parseInt(rawStr.substr(i, 2), 16);
|
||||
resultStr.push(curCharCode);
|
||||
}
|
||||
// encoding为空时默认为utf-8
|
||||
var bytesView = new Uint8Array(resultStr);
|
||||
var str = new TextDecoder(encoding).decode(bytesView);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 输入 json 格式的授信信息
|
||||
* 返回 hex 格式的登录信息
|
||||
*/
|
||||
function auth( info ){
|
||||
var str = "";
|
||||
var manufactor = info.manufactor + " ";
|
||||
manufactor.substr(0, 8);
|
||||
var system = info.system + " ";
|
||||
system.substr(0, 8);
|
||||
var customer = info.customer;
|
||||
str = manufactor + system + customer
|
||||
return stringToHex( str )
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 测试
|
||||
var test = {
|
||||
"manufactor": "sunyard",
|
||||
"system": "hsm",
|
||||
"customer": "ICBC"
|
||||
}
|
||||
|
||||
console.log( auth(test) )
|
||||
|
||||
|
||||
console.log("hexToStr=" + hexToStr("73756e796172642068736d202020202049434243", "UTF-8"))
|
||||
|
||||
// 73756e79617264202020202020202068736d202020202020202049434243
|
||||
// 73756e796172642068736d202020202049434243
|
||||
@@ -0,0 +1,770 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>U 盾维护工具</title>
|
||||
<style>
|
||||
:root {
|
||||
--mainColor: salmon;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: var(--mainColor);
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: 2rem auto;
|
||||
border: var(--mainColor) solid 2px;
|
||||
border-radius: 10px;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
min-height: 500px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.group {
|
||||
padding: 1rem;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.form input {
|
||||
display: block;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
#btn_write_group {
|
||||
display: none;
|
||||
}
|
||||
#mainkey_loaded {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="tabs.css">
|
||||
<link rel="stylesheet" type="text/css" href="layx.min.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div style="width: 100%; text-align: center;">
|
||||
<h2 class="title">信雅达 UKey 发行工具</h2>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
|
||||
|
||||
<div class="group" style="width: 100%; ">
|
||||
<select id="ukeys" style="height: 1.5rem; width: 308px">
|
||||
</select>
|
||||
<button id="btn_refresh" style="margin-right: 1rem">刷  新</button>
|
||||
</div>
|
||||
|
||||
<div class="group" style="width: 100%;">
|
||||
<input id="pwd1" style="width: 300px;height: 1.06rem" type="password" maxlength="8" placeholder="口令,8 个数字">
|
||||
<button id="login" style="margin-right: 1rem">登  录</button>
|
||||
<button id="login_def" style="margin-right: 1rem">默认口令</button>
|
||||
</div>
|
||||
|
||||
<div class="group" style="height: 10rem">
|
||||
<ul class="tabs">
|
||||
<li>
|
||||
<a href="#" name="tab_public">UKey 发行</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#" name="tab_main">主密钥分散</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#" name="tab_main_comp">主密钥合成</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#" name="tab_file">文件操作</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#" name="tab_sign">签名</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="#" name="tab_pin">PIN 管理</a>
|
||||
</li>
|
||||
|
||||
|
||||
<li>
|
||||
<a href="#" name="tab_active">驱动程序</a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
<div class="tabs-content">
|
||||
|
||||
|
||||
<div class="tab tab_public" style="display: none">
|
||||
|
||||
<div class="form">
|
||||
|
||||
<input id="manufactor" style="width: 300px; height: 1.06rem" type="text" value=""
|
||||
placeholder="厂家标记">
|
||||
<input id="system" style="width: 300px; height: 1.06rem" type="text" value="" placeholder="系统信息">
|
||||
<input id="customer" style="width: 300px; height: 1.06rem" type="text" value="" placeholder="客户信息">
|
||||
|
||||
</div>
|
||||
|
||||
<div style="margin: 1rem 0 ">
|
||||
<button id="btn_nameplate_clear" style="margin-right: 1rem">清空</button>
|
||||
<button id="btn_nameplate_tmp_save" style="margin-right: 1rem">临存</button>
|
||||
<button id="btn_nameplate_tmp_load" style="margin-right: 1rem">临取</button>
|
||||
<button id="btn_nameplate_read" style="margin-right: 1rem">返显</button>
|
||||
</div>
|
||||
|
||||
<button id="btn_nameplate_release" style="margin-right: 1rem">发  行</button>
|
||||
|
||||
</div>
|
||||
<div class="tab tab_main" style="display: none">
|
||||
|
||||
<div class="form">
|
||||
<button id="select_file" onclick="read()">请先载入主密钥文件</button>
|
||||
<span id="mainkey_loaded">主密钥已载入,请分别写入三个 UKey</span>
|
||||
</div>
|
||||
|
||||
<div style="margin: 3rem 0" id="btn_write_group">
|
||||
<button id="btn_m1" style="margin-right: 1rem">写入分量1</button>
|
||||
<button id="btn_m2" style="margin-right: 1rem">写入分量2</button>
|
||||
<button id="btn_m3" style="margin-right: 1rem">写入分量3</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="tab tab_main_comp" style="display: none">
|
||||
|
||||
<div style="margin: 3rem 0">
|
||||
<span id="show_m1" style="display: none">[分量1已录入]</span>
|
||||
<button id="btn_loadm1" style="margin-right: 1rem">读取分量1</button>
|
||||
<span id="show_m2" style="display: none">[分量2已录入]</span>
|
||||
<button id="btn_loadm2" style="margin-right: 1rem">写入分量2</button>
|
||||
<span id="show_m3" style="display: none">[分量3已录入]</span>
|
||||
<button id="btn_loadm3" style="margin-right: 1rem">写入分量3</button>
|
||||
</div>
|
||||
|
||||
<div class="form" id="mainkey_out" style="display: none">
|
||||
<p>
|
||||
<span>主密钥已合成,</span><button id="mainkey_comp_show" onclick="downloadMainKey()">点我下载</button><span>!</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="tab tab_file" style="display: none">
|
||||
|
||||
|
||||
<input id="path" style="width: 300px; height: 1.06rem" type="text" value="\root\mana"
|
||||
placeholder="文件目录">
|
||||
<button id="btn_list_path" style="margin-right: 1rem">枚  举</button>
|
||||
|
||||
<textarea id="ta_files" style="display: block; margin: 1rem 0; width: 375px; height: 100px;"
|
||||
readonly></textarea>
|
||||
|
||||
|
||||
<input id="filepath" style="width: 260px; height: 1.06rem" type="text" value="\root\mana\name"
|
||||
placeholder="文件">
|
||||
<button id="btn_read" style="margin-right: 0.5rem">读</button>
|
||||
<button id="btn_write" style="margin-right: 0.5rem">写</button>
|
||||
<button id="btn_delete" style="margin-right: 0.5rem">删</button>
|
||||
|
||||
<textarea id="ta_txt" style="display: block; margin: 1rem 0; width: 375px; height: 100px;"
|
||||
></textarea>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab tab_sign" style="display: none">
|
||||
|
||||
|
||||
<textarea id="inData" style="display: block; margin: 1rem 0; width: 375px; height: 100px;" placeholder="输入签名文本"></textarea>
|
||||
<button id="btn_sign" style="margin-right: 1rem">签  名</button>
|
||||
|
||||
<textarea id="outData" style="display: block; margin: 1rem 0; width: 375px; height: 100px;" readonly></textarea>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab tab_pin" style="display: none">
|
||||
<!-- <div class="group" style="width: 100%; ">-->
|
||||
<!-- <input id="pwd2" style="width: 300px;height: 1.06rem" type="password" maxlength="8"-->
|
||||
<!-- placeholder="口令,8 个数字">-->
|
||||
<!-- <button id="login2" style="margin-right: 1rem">授  权</button>-->
|
||||
<!-- <button id="login_def2" style="margin-right: 1rem">默认口令</button>-->
|
||||
<!-- </div>-->
|
||||
|
||||
|
||||
<div class="form group">
|
||||
<input id="old_pwd" style="width: 360px;height: 1.06rem" type="password" maxlength="8"
|
||||
placeholder="口令,8 个数字">
|
||||
<input id="new_pwd1" style="width: 360px;height: 1.06rem" type="password" maxlength="8"
|
||||
placeholder="新口令,8 个数字">
|
||||
<input id="new_pwd2" style="width: 360px;height: 1.06rem" type="password" maxlength="8"
|
||||
placeholder="重复新口令,8 个数字">
|
||||
<button id="update1" style="margin-right: 1rem">修改操作员 PIN</button>
|
||||
<button id="update2" style="margin-right: 1rem">修改管理员 PIN</button>
|
||||
<button id="reset" style="margin-right: 1rem">解锁操作员 PIN</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tab tab_active" style="display:none; padding-top: 1rem">
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<h4 style="color: var(--mainColor);"><span>【2023年01月01日】</span> V1.0.1 <a href="./Setup_V1.0.1.exe" style="text-decoration:none; font-size: 0.5rem; font-weight: normal; cursor: pointer">(点击下载)</a> </h4>
|
||||
<p>渔翁 UKey</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- UKey 支持, 共 3 个 js-->
|
||||
<!-- jquery -->
|
||||
<script type="text/javascript" src="./jquery.min.js"></script>
|
||||
<script type="text/javascript" src="./fiseckey.js"></script>
|
||||
<script type="text/javascript" src="./ukey.js"></script>
|
||||
|
||||
<script type="application/javascript" src="./gmhelper.js"></script>
|
||||
|
||||
<!-- 演示程序 -->
|
||||
<script type="text/javascript" src="./tabs.js"></script>
|
||||
<script type="application/javascript" src="layx.min.js"></script>
|
||||
<script type="application/javascript" src="tools.js"></script>
|
||||
<script type="application/javascript">
|
||||
$(function () {
|
||||
function refresh() {
|
||||
var list = window.UKey.enumDevByArray()
|
||||
if (list) {
|
||||
var ll = list.split("|");
|
||||
var options = ""
|
||||
for (var i = 0; i < ll.length; i++) {
|
||||
var value = ll[i].split(",")[0]
|
||||
options += "<option value =\"" + value + "\">" + ll[i] + "</option>"
|
||||
}
|
||||
$("#ukeys").html(options);
|
||||
}
|
||||
}
|
||||
|
||||
refresh();
|
||||
|
||||
$("#btn_refresh").click(function () {
|
||||
refresh()
|
||||
success("刷新成功")
|
||||
})
|
||||
|
||||
$("#btn_list_path").click(function () {
|
||||
var path = $("#path").val();
|
||||
try {
|
||||
var ret = window.UKey.enumDir(path)
|
||||
|
||||
var out = ""
|
||||
for (var i = 0; i < ret.folders.length; i++) {
|
||||
out += "文件夹:\t" + ret.folders[i] + "\r\n"
|
||||
}
|
||||
|
||||
for (var i = 0; i < ret.files.length; i++) {
|
||||
out += "文件:\t" + ret.files[i] + "\r\n"
|
||||
}
|
||||
|
||||
$("#ta_files").text(out)
|
||||
success("枚举成功")
|
||||
|
||||
} catch (e) {
|
||||
alert("枚举失败:" + e.message)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
$("#login2").click(function () {
|
||||
var pwd2 = $("#pwd2").val();
|
||||
check(pwd2, /\d{8}/, "口令输入错误")
|
||||
var ukey = $("#ukeys").val();
|
||||
|
||||
try {
|
||||
window.UKey.admin(ukey, pwd2)
|
||||
success("登录成功")
|
||||
} catch (e) {
|
||||
alert("登录失败:" + e.message)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
$("#login_def2").click(function () {
|
||||
var pwd2 = "11111111"
|
||||
$("#pwd2").val(pwd2);
|
||||
var ukey = $("#ukeys").val();
|
||||
|
||||
try {
|
||||
window.UKey.admin(ukey, pwd2)
|
||||
success("登录成功")
|
||||
} catch (e) {
|
||||
alert("登录失败:" + e.message)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
$("#login").click(function () {
|
||||
var pwd1 = $("#pwd1").val();
|
||||
check(pwd1, /\d{8}/, "口令输入错误")
|
||||
var ukey = $("#ukeys").val();
|
||||
|
||||
try {
|
||||
window.UKey.login(ukey, pwd1)
|
||||
success("登录成功")
|
||||
} catch (e) {
|
||||
alert("登录失败:" + e.message)
|
||||
}
|
||||
})
|
||||
|
||||
$("#login_def").click(function () {
|
||||
$("#pwd1").val("12345678");
|
||||
$("#login").click()
|
||||
})
|
||||
|
||||
|
||||
$("#btn_nameplate_clear").click(function () {
|
||||
$("#manufactor").val("");
|
||||
$("#system").val("");
|
||||
$("#customer").val("");
|
||||
})
|
||||
|
||||
$("#btn_read").click(function () {
|
||||
try {
|
||||
var filepath = $("#filepath").val()
|
||||
var idx = filepath.lastIndexOf("\\")
|
||||
var folder = filepath.substr(0, idx)
|
||||
var file = filepath.substr(idx + 1)
|
||||
var txt = window.UKey.readFile(folder, file);
|
||||
txt = JSON.stringify(txt, null, 4)
|
||||
|
||||
$("#ta_txt").val( txt )
|
||||
success("读取成功")
|
||||
} catch (e) {
|
||||
alert("读取失败:" + e.message)
|
||||
}
|
||||
})
|
||||
|
||||
$("#btn_write").click(function () {
|
||||
// alert("暂不开放")
|
||||
try {
|
||||
var filepath = $("#filepath").val()
|
||||
var idx = filepath.lastIndexOf("\\")
|
||||
var folder = filepath.substr(0, idx)
|
||||
var file = filepath.substr(idx + 1)
|
||||
|
||||
|
||||
var txt = $("#ta_txt").val();
|
||||
window.UKey.writeFile(folder, file, txt);
|
||||
success("写入成功")
|
||||
} catch (e) {
|
||||
alert("写入失败:" + e.message)
|
||||
}
|
||||
})
|
||||
|
||||
$("#btn_delete").click(function () {
|
||||
// alert("暂不开放")
|
||||
try {
|
||||
var filepath = $("#filepath").val()
|
||||
var idx = filepath.lastIndexOf("\\")
|
||||
var folder = filepath.substr(0, idx)
|
||||
var file = filepath.substr(idx + 1)
|
||||
|
||||
window.UKey.deleteFile(folder, file);
|
||||
success("删除成功")
|
||||
} catch (e) {
|
||||
alert("删除失败:" + e.message)
|
||||
}
|
||||
})
|
||||
|
||||
$("#btn_nameplate_tmp_load").click(function () {
|
||||
var def = {
|
||||
manufactor: "sunyard",
|
||||
system: "hsm",
|
||||
customer: "ICBC"
|
||||
}
|
||||
$("#manufactor").val(def.manufactor);
|
||||
$("#system").val(def.system);
|
||||
$("#customer").val(def.customer);
|
||||
})
|
||||
|
||||
$("#btn_nameplate_read").click(function () {
|
||||
|
||||
try {
|
||||
var txt = window.UKey.catRelease();
|
||||
var def = Object.assign({
|
||||
manufactor: "",
|
||||
system: "",
|
||||
customer: ""
|
||||
}, txt)
|
||||
|
||||
$("#manufactor").val(def.manufactor);
|
||||
$("#system").val(def.system);
|
||||
$("#customer").val(def.customer);
|
||||
|
||||
success("返显成功")
|
||||
} catch (e) {
|
||||
alert("返显失败:" + e.message)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
$("#btn_nameplate_tmp_load").click(function () {
|
||||
|
||||
|
||||
var json = localStorage.getItem("tmp")
|
||||
var def = {
|
||||
manufactor: "sunyard",
|
||||
system: "hsm",
|
||||
customer: "ICBC"
|
||||
}
|
||||
try {
|
||||
def = JSON.parse(json)
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
|
||||
$("#manufactor").val(def.manufactor);
|
||||
$("#system").val(def.system);
|
||||
$("#customer").val(def.customer);
|
||||
})
|
||||
|
||||
|
||||
$("#btn_nameplate_tmp_save").click(function () {
|
||||
var def = {
|
||||
manufactor: $("#manufactor").val(),
|
||||
system: $("#system").val(),
|
||||
customer: $("#customer").val()
|
||||
}
|
||||
|
||||
localStorage.setItem("tmp", JSON.stringify(def))
|
||||
|
||||
})
|
||||
|
||||
$("#btn_nameplate_release").click(function () {
|
||||
var def = {
|
||||
manufactor: $("#manufactor").val(),
|
||||
system: $("#system").val(),
|
||||
customer: $("#customer").val()
|
||||
}
|
||||
|
||||
check(def.manufactor, /\w+/, "厂家标记填写错误")
|
||||
check(def.system, /\w+/, "系统信息填写错误")
|
||||
check(def.customer, /\w+/, "客户信息填写错误")
|
||||
|
||||
try {
|
||||
window.UKey.release(def)
|
||||
success("发行成功")
|
||||
} catch (e) {
|
||||
alert("发行失败:" + e.message)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
$("#btn_sign").click(function () {
|
||||
var inData = $("#inData").val()
|
||||
|
||||
// 公钥
|
||||
var pk = window.UKey.exportPk();
|
||||
|
||||
var s = window.gmhelper.getHashAsBase64( inData, pk )
|
||||
|
||||
|
||||
|
||||
var outData = pk
|
||||
|
||||
outData += "\r\n\r\nz=" + s.z
|
||||
|
||||
outData += "\r\n\r\nhash=" + s.hashHex
|
||||
|
||||
var sign = window.UKey.sign( s.hashBase64 )
|
||||
outData += "\r\n\r\nsign=" + sign
|
||||
|
||||
$("#outData").text(outData)
|
||||
})
|
||||
|
||||
|
||||
$("#reset").click(function () {
|
||||
var ukey = $("#ukeys").val();
|
||||
// 重置口令
|
||||
var old_pwd = $("#old_pwd").val()
|
||||
|
||||
try {
|
||||
window.UKey.admin(ukey, old_pwd)
|
||||
success("授权成功")
|
||||
} catch (e) {
|
||||
alert("授权失败:" + e.message)
|
||||
return
|
||||
}
|
||||
|
||||
var new_pwd1 = $("#new_pwd1").val()
|
||||
var new_pwd2 = $("#new_pwd2").val()
|
||||
|
||||
if ( new_pwd1 !== new_pwd2 ) {
|
||||
alert("新口令两次不同")
|
||||
} else {
|
||||
window.UKey.updatePin(3, old_pwd, new_pwd1);
|
||||
alert("执行成功")
|
||||
}
|
||||
|
||||
})
|
||||
$("#update1").click(function () {
|
||||
var old_pwd = $("#old_pwd").val()
|
||||
var new_pwd1 = $("#new_pwd1").val()
|
||||
var new_pwd2 = $("#new_pwd2").val()
|
||||
|
||||
if ( new_pwd1 !== new_pwd2 ) {
|
||||
alert("新口令两次不同")
|
||||
} else {
|
||||
window.UKey.updatePin(1, old_pwd, new_pwd1);
|
||||
alert("执行成功")
|
||||
}
|
||||
})
|
||||
$("#update2").click(function () {
|
||||
var old_pwd = $("#old_pwd").val()
|
||||
var new_pwd1 = $("#new_pwd1").val()
|
||||
var new_pwd2 = $("#new_pwd2").val()
|
||||
|
||||
if ( new_pwd1 !== new_pwd2 ) {
|
||||
alert("新口令两次不同")
|
||||
} else {
|
||||
window.UKey.updatePin(2, old_pwd, new_pwd1);
|
||||
alert("执行成功")
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
function read() {
|
||||
var input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
|
||||
input.click() // 开始选择文件
|
||||
input.onchange = () => { // 监听选择文件的结果,获取选择到的文件
|
||||
var file = input.files[0]
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
console.log(this.result);
|
||||
console.log(e.target.result)
|
||||
console.log(e.target.result.byteLength)
|
||||
|
||||
if ( ! e.target.result || 16 !== e.target.result.byteLength ) {
|
||||
alert("文件格式错误")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
$("#btn_write_group").show();
|
||||
$("#mainkey_loaded").show();
|
||||
$("#select_file").hide();
|
||||
|
||||
|
||||
window.mk = e.target.result
|
||||
|
||||
}
|
||||
reader.readAsArrayBuffer(file);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$("#btn_m1").click(function (){
|
||||
|
||||
var d = gmhelper.decentralizedMainKey(window.mk)
|
||||
publicWrite('\\root\\mana\\a20', { data: '31'})
|
||||
publicWrite('\\root\\mana\\a30', { data: d.m.checkValue}) // 主密钥校验值
|
||||
publicWrite('\\root\\mana\\a40', { data: d.m.keyCiphertext}) // 主密钥密文
|
||||
publicWrite('\\root\\mana\\a50', { data: d.p.checkValue}) // 保护密钥校验值
|
||||
publicWrite('\\root\\mana\\a60', { data: d.p1}) // 保护分量1
|
||||
success("写入成功")
|
||||
|
||||
})
|
||||
|
||||
$("#btn_m2").click(function (){
|
||||
|
||||
var d = gmhelper.decentralizedMainKey(window.mk)
|
||||
publicWrite('\\root\\mana\\a20', { data: '32'})
|
||||
publicWrite('\\root\\mana\\a30', { data: d.m.checkValue}) // 主密钥校验值
|
||||
publicWrite('\\root\\mana\\a40', { data: d.m.keyCiphertext}) // 主密钥密文
|
||||
publicWrite('\\root\\mana\\a50', { data: d.p.checkValue}) // 保护密钥校验值
|
||||
publicWrite('\\root\\mana\\a60', { data: d.p2}) // 保护分量2
|
||||
|
||||
success("写入成功")
|
||||
})
|
||||
|
||||
$("#btn_m3").click(function (){
|
||||
|
||||
var d = gmhelper.decentralizedMainKey(window.mk)
|
||||
publicWrite('\\root\\mana\\a20', { data: '33'})
|
||||
publicWrite('\\root\\mana\\a30', { data: d.m.checkValue}) // 主密钥校验值
|
||||
publicWrite('\\root\\mana\\a40', { data: d.m.keyCiphertext}) // 主密钥密文
|
||||
publicWrite('\\root\\mana\\a50', { data: d.p.checkValue}) // 保护密钥校验值
|
||||
publicWrite('\\root\\mana\\a60', { data: d.p3}) // 保护分量3
|
||||
|
||||
success("写入成功")
|
||||
})
|
||||
|
||||
function publicWrite(filepath, txt) {
|
||||
try {
|
||||
const idx = filepath.lastIndexOf("\\")
|
||||
const folder = filepath.substr(0, idx)
|
||||
const file = filepath.substr(idx + 1)
|
||||
window.UKey.writeFile(folder, file, JSON.stringify(txt));
|
||||
} catch (e) {
|
||||
alert("写入失败:" + e.message)
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
function publicRead(filepath) {
|
||||
let txt = ''
|
||||
try {
|
||||
const idx = filepath.lastIndexOf("\\")
|
||||
const folder = filepath.substr(0, idx)
|
||||
const file = filepath.substr(idx + 1)
|
||||
txt = window.UKey.readFile(folder, file);
|
||||
return txt.data;
|
||||
} catch (e) {
|
||||
alert("读取失败:" + e.message)
|
||||
}
|
||||
return txt
|
||||
}
|
||||
|
||||
|
||||
function readKey( p ){
|
||||
var role = publicRead('\\root\\mana\\a20')
|
||||
console.log("role", role);
|
||||
if ( role != p ) {
|
||||
alert("分量编号错误")
|
||||
return
|
||||
}
|
||||
|
||||
if ( ! window.mk ) {
|
||||
window.mk = {}
|
||||
}
|
||||
|
||||
if ( 31 == p ) {
|
||||
window.mk.weight0x30 = publicRead('\\root\\mana\\a30')
|
||||
window.mk.weight0x40 = publicRead('\\root\\mana\\a40')
|
||||
window.mk.weight0x401 = publicRead('\\root\\mana\\a40')
|
||||
window.mk.weight0x50 = publicRead('\\root\\mana\\a50')
|
||||
window.mk.weight0x60 = publicRead('\\root\\mana\\a60')
|
||||
window.mk.weight0x601 = publicRead('\\root\\mana\\a60')
|
||||
} else if ( 32 == p ) {
|
||||
window.mk.weight0x402 = publicRead('\\root\\mana\\a40')
|
||||
window.mk.weight0x602 = publicRead('\\root\\mana\\a60')
|
||||
} else if ( 33 == p ) {
|
||||
|
||||
window.mk.weight0x403 = publicRead('\\root\\mana\\a40')
|
||||
window.mk.weight0x603 = publicRead('\\root\\mana\\a60')
|
||||
|
||||
} else {
|
||||
alert("分量编号错误")
|
||||
}
|
||||
|
||||
// 每次都执行
|
||||
$("#btn_loadm" + ( p - 30 )).hide()
|
||||
$("#show_m" + ( p - 30 )).show()
|
||||
|
||||
// 全部结束后执行
|
||||
if ( window.mk.weight0x601 && window.mk.weight0x602 && window.mk.weight0x603 ) {
|
||||
var mk = checkValue( window.mk.weight0x601, window.mk.weight0x602, window.mk.weight0x603 )
|
||||
if ( mk ) {
|
||||
$("#mainkey_out").show();
|
||||
window.mkd = mk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$("#btn_loadm1").click(function (){
|
||||
readKey( 31 )
|
||||
})
|
||||
|
||||
$("#btn_loadm2").click(function (){
|
||||
readKey( 32 )
|
||||
})
|
||||
|
||||
$("#btn_loadm3").click(function (){
|
||||
readKey( 33 )
|
||||
})
|
||||
|
||||
// 将十六进制字符串转换为二进制数组
|
||||
function hexToBytes(hex) {
|
||||
const bytes = new Uint8Array(hex.length / 2);
|
||||
for (let i = 0; i < hex.length; i += 2) {
|
||||
bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
function downloadMainKey(){
|
||||
|
||||
// 创建一个Blob对象
|
||||
const bytes = hexToBytes(window.mkd);
|
||||
const blob = new Blob([bytes], { type: 'application/octet-stream' });
|
||||
|
||||
// 生成一个临时的URL
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
|
||||
// 创建一个a标签并设置为下载链接
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.href = blobUrl;
|
||||
downloadLink.download = 'MainKey.Dat'; // 指定下载文件的名称
|
||||
|
||||
// 触发a标签的点击事件以开始下载
|
||||
document.body.appendChild(downloadLink);
|
||||
downloadLink.click();
|
||||
document.body.removeChild(downloadLink);
|
||||
|
||||
// 清理URL
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
}
|
||||
|
||||
function checkValue(p1, p2, p3){
|
||||
const protectKey = window.gmhelper.xor(p1, p2, p3)
|
||||
const protectKcv = window.gmhelper.kcv( protectKey )
|
||||
if ( protectKcv.toUpperCase().substr(0, 8) != window.mk.weight0x50.toUpperCase()) {
|
||||
alert('保护密钥校验值错误!!!')
|
||||
return false
|
||||
}
|
||||
var finalMainKey = window.gmhelper.decryptKey(window.mk.weight0x40 , protectKey) // 解密
|
||||
const mainKcv = window.gmhelper.kcv( finalMainKey )
|
||||
if ( mainKcv.toUpperCase().substr(0, 8) !== window.mk.weight0x30.toUpperCase()) {
|
||||
alert('主密钥校验值错误!!!')
|
||||
return false
|
||||
}
|
||||
return finalMainKey;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+4
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+5
File diff suppressed because one or more lines are too long
@@ -0,0 +1,59 @@
|
||||
.tabs {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.tabs li {
|
||||
float: left;
|
||||
margin: 0 -15px 0 0;
|
||||
}
|
||||
|
||||
.tabs a {
|
||||
float: left;
|
||||
position: relative;
|
||||
padding: 0 40px;
|
||||
height: 0;
|
||||
line-height: 30px;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
border-right: 30px solid transparent;
|
||||
border-bottom: 30px solid var(--mainColor);
|
||||
/*border-bottom-color: #777 \9;*/
|
||||
opacity: .3;
|
||||
filter: alpha(opacity=30);
|
||||
}
|
||||
|
||||
.tabs a:hover {
|
||||
border-bottom-color: var(--mainColor);
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
|
||||
.tabs a:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.tabs-content .tabs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tabs .current {
|
||||
z-index: 3;
|
||||
border-bottom-color: var(--mainColor);
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
|
||||
.tabs-content {
|
||||
background: #fff;
|
||||
border-top: 2px solid var(--mainColor);
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.tabs-content h2, #content h3, #content p {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
$(function (){
|
||||
|
||||
var $e = $(".tabs a").first();
|
||||
$e.addClass("current")
|
||||
showHideBlock( $e )
|
||||
|
||||
function showHideBlock($e){
|
||||
$(".tabs-content .tab").hide()
|
||||
var block = ".tabs-content .tab" + "." + $e.attr("name")
|
||||
$(block).show()
|
||||
}
|
||||
|
||||
|
||||
$(".tabs a").click(function (){
|
||||
$(".tabs a").removeClass("current")
|
||||
$(this).addClass("current")
|
||||
showHideBlock( $(this) )
|
||||
})
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
// 覆盖默认行为
|
||||
function success(msg){
|
||||
layx.notice({
|
||||
title: '成功',
|
||||
type: 'success',
|
||||
message: msg
|
||||
});
|
||||
}
|
||||
|
||||
// 覆盖默认行为
|
||||
function warning(msg){
|
||||
layx.notice({
|
||||
title: '警告',
|
||||
type: 'warning',
|
||||
message: msg
|
||||
});
|
||||
}
|
||||
|
||||
// 覆盖默认行为
|
||||
function alert(msg){
|
||||
layx.notice({
|
||||
title: '错误',
|
||||
type: 'error',
|
||||
message: msg
|
||||
});
|
||||
}
|
||||
|
||||
function check(v, re, msg) {
|
||||
if (!re.test(v)) {
|
||||
alert("参数校验失败:" + msg)
|
||||
throw "参数校验失败"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getyyyyMMdd(){
|
||||
var d = new Date();
|
||||
var curr_date = d.getDate();
|
||||
var curr_month = d.getMonth() + 1;
|
||||
var curr_year = d.getFullYear();
|
||||
String(curr_month).length < 2 ? (curr_month = "0" + curr_month): curr_month;
|
||||
String(curr_date).length < 2 ? (curr_date = "0" + curr_date): curr_date;
|
||||
var yyyyMMdd = curr_year + "" + curr_month +""+ curr_date;
|
||||
return yyyyMMdd;
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
(function( root ){
|
||||
|
||||
var DIR = "\\root\\mana"
|
||||
var FISECKEY = root.FISECKEY;
|
||||
var hDevice = undefined;
|
||||
var fileSize = 4 * 1024;
|
||||
|
||||
if ( ! FISECKEY ) {
|
||||
console.error("缺少 FISECKEY 支持 !!!")
|
||||
}
|
||||
|
||||
function stringToHex(str){
|
||||
var val = "";
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
var v = str.charCodeAt(i).toString(16);
|
||||
if ( v.length < 2 ) {
|
||||
v = "0" + v;
|
||||
}
|
||||
val += v;
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
function hexToString(hex){
|
||||
var arr = hex.split("")
|
||||
var out = ""
|
||||
for (var i = 0; i < arr.length / 2; i++) {
|
||||
var tmp = "0x" + arr[i * 2] + arr[i * 2 + 1]
|
||||
var charValue = String.fromCharCode(tmp);
|
||||
out += charValue
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
|
||||
function admin( dev, pin ){
|
||||
if ( ! hDevice ) {
|
||||
hDevice = FISECKEY.OpenBySerial(dev, "4");
|
||||
}
|
||||
if ( ! hDevice ) {
|
||||
throw new Error("设备打开失败")
|
||||
}
|
||||
FISECKEY.ADMIN_Login(hDevice, pin);
|
||||
return hDevice;
|
||||
}
|
||||
|
||||
function login( dev, pin ){
|
||||
hDevice = FISECKEY.OpenBySerial(dev, "4");
|
||||
if ( ! hDevice ) {
|
||||
throw new Error("设备打开失败")
|
||||
}
|
||||
FISECKEY.USER_Login(hDevice, pin);
|
||||
return hDevice;
|
||||
}
|
||||
|
||||
function logout(){
|
||||
FISECKEY.USER_Logout(hDevice, 0);
|
||||
FISECKEY.CloseDevice(hDevice);
|
||||
hDevice = undefined
|
||||
}
|
||||
|
||||
function sumHash(data){
|
||||
var sum = 0;
|
||||
for (var i =0 ; i < data.length; i++) {
|
||||
sum += data.charCodeAt(i)
|
||||
}
|
||||
|
||||
sum += "";
|
||||
if ( sum.length < 4 ) {
|
||||
sum = "0000" + sum
|
||||
}
|
||||
// 截取最后 2 字节
|
||||
return sum.substr( sum.length -4 );
|
||||
}
|
||||
|
||||
function release( info ){
|
||||
if ( ! hDevice ) {
|
||||
throw new Error("设备未登录")
|
||||
}
|
||||
FISECKEY.FILE_Init(hDevice);
|
||||
|
||||
|
||||
FISECKEY.FILE_CreateDir(hDevice, DIR, 0);
|
||||
FISECKEY.FILE_CreateFile(hDevice, DIR, "name", 1024, 0);
|
||||
|
||||
|
||||
FISECKEY.GenECCKeypair(hDevice, 0, 256, 1);
|
||||
|
||||
var data = JSON.stringify(info)
|
||||
|
||||
writeFile(DIR, "name", data, 1024)
|
||||
|
||||
readFile(DIR, "name")
|
||||
|
||||
}
|
||||
|
||||
function deleteFile(dir, file){
|
||||
if ( ! hDevice ) {
|
||||
throw new Error("设备未登录")
|
||||
}
|
||||
|
||||
FISECKEY.FILE_DeleteFile(hDevice, dir, file);
|
||||
}
|
||||
|
||||
|
||||
function readData(hDevice, dir, file, off, len){
|
||||
var data = "";
|
||||
|
||||
if ( len <= 1024 ) {
|
||||
return FISECKEY.FILE_ReadFile(hDevice, dir, file, off, len);
|
||||
}
|
||||
else {
|
||||
var curLen = 0;
|
||||
while ( curLen < len ) {
|
||||
|
||||
var readLen = 1024;
|
||||
if ( (len - curLen) <= 1024 ) {
|
||||
// 剩余量小于= 1024
|
||||
readLen = len - curLen;
|
||||
} else {
|
||||
// 剩余量大于 1024
|
||||
readLen = 1024
|
||||
}
|
||||
|
||||
data += FISECKEY.FILE_ReadFile(hDevice, dir, file, off + curLen, readLen);
|
||||
curLen += readLen
|
||||
}
|
||||
return data;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function readFile(dir, file) {
|
||||
if ( ! hDevice ) {
|
||||
throw new Error("设备未登录")
|
||||
}
|
||||
|
||||
var len = FISECKEY.FILE_ReadFile(hDevice, dir, file, 0, 3);
|
||||
console.log("read "+ file + " lenAsHex=", len, )
|
||||
len = parseInt( len, 10 );
|
||||
console.log("read "+ file + " len=", len)
|
||||
|
||||
var data = readData(hDevice, dir, file, 3, len);
|
||||
console.log("read "+ file + " data=", data)
|
||||
var sum = sumHash(data);
|
||||
|
||||
|
||||
var hash = FISECKEY.FILE_ReadFile(hDevice, dir, file, 3 + len, 2);
|
||||
|
||||
|
||||
if ( sum === hash ) {
|
||||
|
||||
var str = hexToString(data);
|
||||
console.log( "read", data )
|
||||
return JSON.parse(str);
|
||||
}
|
||||
throw new Error("文件读取失败")
|
||||
}
|
||||
|
||||
function writeData(hDevice, dir, file, idx, len, data){
|
||||
|
||||
if ( len <= 400 ) {
|
||||
FISECKEY.FILE_WriteFile(hDevice, dir, file, idx, len, data);
|
||||
} else {
|
||||
// 先写入 400
|
||||
FISECKEY.FILE_WriteFile(hDevice, dir, file, idx, 400, data.substr(0, 800 ));
|
||||
writeData( hDevice, dir, file, idx + 400, len - 400, data.substr(800) )
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function writeFile(dir, file, data, keep, size){
|
||||
if ( ! hDevice ) {
|
||||
throw new Error("设备未登录")
|
||||
}
|
||||
|
||||
if ( ! keep ) {
|
||||
if ( !size ) {
|
||||
size = fileSize
|
||||
}
|
||||
|
||||
try {
|
||||
FISECKEY.FILE_DeleteFile(hDevice, dir, file);
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
FISECKEY.FILE_CreateFile(hDevice, dir, file, size, 0);
|
||||
}
|
||||
|
||||
console.log( "write "+ file + " data=", data )
|
||||
console.log( "write "+ file + " data.length" , data.length )
|
||||
data = stringToHex( data ).toUpperCase()
|
||||
|
||||
|
||||
var len = data.length / 2
|
||||
len = "000000" + len;
|
||||
len = len.substr( len.length -6 );
|
||||
console.log("write "+ file + " head=", len)
|
||||
FISECKEY.FILE_WriteFile(hDevice, dir, file, 0, 3, len);
|
||||
writeData(hDevice, dir, file, 3, data.length/2, data)
|
||||
|
||||
// console.log( "writeFile=" + len )
|
||||
// console.log( "writeFile=" + data )
|
||||
// console.log( "writeFile=" + data.length )
|
||||
|
||||
|
||||
var hash = sumHash(data);
|
||||
console.log("write "+ file + " hash=", hash)
|
||||
// console.log( "writeFile hash=" + hash )
|
||||
FISECKEY.FILE_WriteFile(hDevice, dir, file, 3 + (data.length/2), 2, hash);
|
||||
}
|
||||
|
||||
// 枚举序列号与名称
|
||||
function enumDevByArray() {
|
||||
return FISECKEY.EnumByArray();
|
||||
}
|
||||
|
||||
|
||||
function enumDir( path ){
|
||||
if ( ! hDevice ) {
|
||||
throw new Error("设备未登录")
|
||||
}
|
||||
var folders = FISECKEY.FILE_EnmuDir(hDevice, path);
|
||||
var fos = folders.split("|")
|
||||
folders = []
|
||||
for ( var i = 0 ; i < fos.length ; i++ ) {
|
||||
if ( fos[i] ) {
|
||||
folders.push( path + "\\" + fos[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var files = FISECKEY.FILE_EnmuFile(hDevice, path);
|
||||
var fs = files.split("|")
|
||||
files = []
|
||||
for ( var i = 0 ; i < fs.length ; i++ ) {
|
||||
if ( fs[i] ) {
|
||||
files.push( path + "\\" + fs[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
folders : folders,
|
||||
files : files
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function loadLMK(){
|
||||
return readFile(DIR, "lmk")
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param no 1/2/3
|
||||
* @param mkey HEX(48 字节)
|
||||
*/
|
||||
function saveLMK(no, lmk, pk, sk) {
|
||||
if ( ! hDevice ) {
|
||||
throw new Error("设备未登录")
|
||||
}
|
||||
|
||||
var info = {
|
||||
pk : pk , sk : sk
|
||||
}
|
||||
|
||||
switch ( no ) {
|
||||
case 1: {
|
||||
info = Object.assign( info, {
|
||||
no : no,
|
||||
lmk1 : lmk.substr(0, 32),
|
||||
lmk2 : lmk.substr(32, 64)
|
||||
})
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// 0 16 32 48
|
||||
// 0 32 64 96
|
||||
info = Object.assign( info, {
|
||||
no : no,
|
||||
lmk2 : lmk.substr(32, 64),
|
||||
lmk3 : lmk.substr(64, 96)
|
||||
})
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
info = Object.assign( info, {
|
||||
no : no,
|
||||
lmk3 : lmk.substr(64, 96),
|
||||
lmk1 : lmk.substr(0, 32)
|
||||
})
|
||||
break;
|
||||
}
|
||||
default :
|
||||
throw new Error("不支持的分量")
|
||||
}
|
||||
|
||||
var data = JSON.stringify(info)
|
||||
FISECKEY.FILE_DeleteFile(hDevice, DIR, "lmk");
|
||||
FISECKEY.FILE_CreateFile(hDevice, DIR, "lmk", fileSize, 0);
|
||||
writeFile( DIR, "lmk" , data);
|
||||
|
||||
|
||||
var auth = {
|
||||
uid : no,
|
||||
rid : no
|
||||
}
|
||||
|
||||
FISECKEY.FILE_DeleteFile(hDevice, DIR, "auth");
|
||||
FISECKEY.FILE_CreateFile(hDevice, DIR, "auth", fileSize, 0);
|
||||
writeFile( DIR, "auth" , auth);
|
||||
}
|
||||
|
||||
function saveAuth(uid, rid){
|
||||
var auth = {
|
||||
uid : no,
|
||||
rid : no
|
||||
}
|
||||
|
||||
FISECKEY.FILE_DeleteFile(hDevice, DIR, "auth");
|
||||
FISECKEY.FILE_CreateFile(hDevice, DIR, "auth", fileSize, 0);
|
||||
writeFile( DIR, "auth" , auth);
|
||||
}
|
||||
|
||||
function loadAuth(){
|
||||
return readFile(DIR, "auth")
|
||||
}
|
||||
|
||||
function catRelease(){
|
||||
return readFile(DIR, "name")
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改口令
|
||||
*/
|
||||
function updatePin(flag, oldpin, newpin){
|
||||
FISECKEY.USER_ChangePin(hDevice, 3, oldpin, newpin);
|
||||
}
|
||||
|
||||
function exportPk(){
|
||||
return FISECKEY.ExportECCKeypair(hDevice, 1);
|
||||
}
|
||||
|
||||
function sign(vInbuf){
|
||||
return FISECKEY.ECCSign(hDevice, 1, 1, vInbuf);
|
||||
}
|
||||
|
||||
root.UKey = {
|
||||
release: release,
|
||||
catRelease : catRelease,
|
||||
readFile: readFile,
|
||||
writeFile : writeFile,
|
||||
deleteFile : deleteFile,
|
||||
login : login,
|
||||
logout : logout,
|
||||
updatePin : updatePin,
|
||||
admin : admin,
|
||||
enumDevByArray : enumDevByArray,
|
||||
enumDir: enumDir,
|
||||
saveLMK : saveLMK,
|
||||
loadLMK : loadLMK,
|
||||
saveAuth : saveAuth,
|
||||
loadAuth : loadAuth,
|
||||
exportPk : exportPk,
|
||||
sign : sign
|
||||
}
|
||||
})( window )
|
||||
Reference in New Issue
Block a user