完成协议开发

This commit is contained in:
Cheney 2024-08-19 18:01:01 +08:00
parent 422d44df1b
commit 00de726082
4 changed files with 310 additions and 7 deletions

View File

@ -1,6 +1,8 @@
# Fake UKey # Fake UKey
1. 暂时无法实现 UKEY 复制, 只能从初始化时就使用 Fake UKEY。 1. 与渔翁 UKEY 协议完全兼容。内置 7 个虚拟 UKEY。
2. 与渔翁 UKEY 驱动冲突。启动时会尝试强制剔除渔翁 UKEY但是建议手工退出渔翁 UKEY 驱动。
3. 暂时无法实现 UKEY 复制, 只能从初始化时就使用 Fake UKEY。
## API ## API

1
api.md
View File

@ -1 +0,0 @@
enumDevByArray

265
backend/src/FakeUKey.js Normal file
View File

@ -0,0 +1,265 @@
const config = require("./Config")
const fs = require("fs")
const path = require("path");
function listFakeUKeys(){
let ukeyDir = config.getFakeUKeyDir();
const files = fs.readdirSync(ukeyDir);
return files;
}
function checkFakeUKey(name){
let ukeyDir = config.getFakeUKeyDir();
return fs.existsSync(path.resolve(ukeyDir, name))
}
function checkUKeyPIN(dev, pin) {
let ukeyDir = config.getFakeUKeyDir();
let ppin = fs.readFileSync(path.resolve(ukeyDir, dev, "pin.txt"), "utf-8")
return pin === ppin
}
module.exports = {
// 枚举设备
"01000005" : function () {
let nameList = listFakeUKeys()
return {
"EnumDeviceNameList": nameList.join("|"),
}
},
// 打开设备
"01000004" : function (params) {
let ukey = params.devSerial
if ( checkFakeUKey( ukey ) ) {
return {"hdev": ukey}
} else {
throw "找不到设备"
}
},
// PIN 登录
"01000027" : function (params) {
let ukey = params.hdevice
let pin = params.pin
if ( checkUKeyPIN(ukey, pin) ) {
return {"huser":"", "count":0, "rev":0}
} else {
throw "PIN 验证错误"
}
},
// 文件系统初始化
"01000031" : function (params) {
let ukey = params.hdevice
if ( fs.existsSync(path.resolve(config.getFakeUKeyDir(), ukey, "root")) ) {
return {};
}
throw "目录损坏"
},
// 创建目录
"01000032" : function (params) {
let ukey = params.hdevice
let dir = params.dir
let acc = params.acc
if ( dir.startsWith("\\root\\") ) {
dir = dir.substring(6);
fs.mkdirSync(path.resolve(config.getFakeUKeyDir(), ukey, "root", dir), { recursive: true });
return {}
} else {
throw "目录不合法"
}
},
// 创建文件
"01000034" : function (params) {
let ukey = params.hdevice
let dir = params.dir
let file = params.file
let size = params.size
let acc = params.acc
if ( dir.startsWith("\\root\\") ) {
dir = dir.substring(6);
if ( fs.existsSync(path.resolve(config.getFakeUKeyDir(), ukey, "root", dir)) ) {
// throw "文件已存在"
return {}
}
} else {
throw "目录不合法"
}
},
// 读取文件
"01000035" : function (params) {
let ukey = params.hdevice
let dir = params.dir
let file = params.file
let size = parseInt(params.size, 10)
let offset = parseInt(params.offset, 10)
if ( dir.startsWith("\\root\\") ) {
dir = dir.substring(6);
let f = path.resolve(config.getFakeUKeyDir(), ukey, "root\\", dir, file)
let buffer = fs.readFileSync(f);
return {
data : buffer.slice(offset, offset + size).toString("HEX").toUpperCase()
}
} else {
throw "目录不合法"
}
},
// 写入文件
"01000036" : function (params) {
let ukey = params.hdevice
let dir = params.dir
let file = params.file
let size = params.size
let offset = parseInt(params.offset, 10)
let input = params.input
if ( dir.startsWith("\\root\\") ) {
dir = dir.substring(6);
let f = path.resolve(config.getFakeUKeyDir(), ukey, "root\\", dir, file)
let buffer = undefined;
if ( offset === 0 ) {
buffer = Buffer.from(input, 'hex');
} else {
if ( fs.existsSync( f ) ) {
buffer = fs.readFileSync(f);
buffer = buffer.slice(0, offset);
} else {
buffer = Buffer.alloc(offset);
}
buffer = Buffer.concat([buffer, Buffer.from(input, 'hex')])
}
fs.writeFileSync(f, buffer)
return {}
} else {
throw "目录不合法"
}
},
// 删除文件
"01000037" : function (params) {
let ukey = params.hdevice
let dir = params.dir
let file = params.file
if ( ! dir.startsWith("\\root\\") ) {
throw "目录不合法"
}
dir = dir.substring(6);
let f = path.resolve(config.getFakeUKeyDir(), ukey, "root\\", dir, file)
fs.unlinkSync( f )
return {}
},
// 枚举文件夹
"01000038" : function (params) {
let ukey = params.hdevice
let dir = params.dir
if ( ! dir.startsWith("\\root\\") ) {
throw "目录不合法"
}
dir = dir.substring(6);
let f = path.resolve(config.getFakeUKeyDir(), ukey, "root\\", dir)
let list = fs.readdirSync(f)
let files = []
for ( let fname of list ) {
let p = path.resolve(f, fname)
if ( fs.statSync( p ).isFile() ) {
files.push( fname )
}
}
},
// 枚举文件
"01000039" : function (params) {
let ukey = params.hdevice
let dir = params.dir
if ( ! dir.startsWith("\\root\\") ) {
throw "目录不合法"
}
dir = dir.substring(6);
let f = path.resolve(config.getFakeUKeyDir(), ukey, "root\\", dir)
let list = fs.readdirSync(f)
let files = []
for ( let fname of list ) {
let p = path.resolve(f, fname)
if ( ! fs.statSync( p ).isFile() ) {
files.push( fname )
}
}
},
// 生成密钥对
"01000040" : function (params) {
let ukey = params.hdevice
let alg = params.alg
let keyNum = params.keyNum
let keyLen = params.keyLen
const sm2 = require('sm-crypto').sm2
let keypair = sm2.generateKeyPairHex()
let ukeyDir = config.getFakeUKeyDir();
fs.writeFileSync(path.resolve(ukeyDir, ukey, keyNum + ".key"), JSON.stringify(keypair, null, 4))
return {}
},
// 导出公钥
"01000043" : function (params) {
let ukey = params.hdevice
let keyNum = params.keyNum
let ukeyDir = config.getFakeUKeyDir();
let keyJson = fs.readFileSync(path.resolve(ukeyDir, ukey, keyNum + ".key"), "UTF-8")
let key = JSON.parse(keyJson)
let pubkey = Buffer.from(key.publicKey, "hex").toString("base64")
return {
keyData : "-----BEGIN ECDSA PUBLIC KEY-----" + pubkey + "-----END ECDSA PUBLIC KEY-----"
}
},
// 签名
"01000046" : function (params) {
let ukey = params.hdevice
let keyNum = params.keyNum
let inData = params.inData
let ukeyDir = config.getFakeUKeyDir();
let keyJson = fs.readFileSync(path.resolve(ukeyDir, ukey, keyNum + ".key"), "UTF-8")
let key = JSON.parse(keyJson)
let sigValueHex = sm2.doSignature(Buffer.from(inData, "base64"), key.privateKey) // 签名
return {
sigData : Buffer.from(sigValueHex, "HEX").toString("base64")
}
}
}

View File

@ -1,11 +1,18 @@
const express = require('express'); const express = require('express');
const bodyParser = require('body-parser'); const bodyParser = require('body-parser');
const ukey = require("./FakeUKey")
const cors = require('cors');
const { killPortProcess } = require('kill-port-process');
const app = express(); const app = express();
const port = 3000; // const port = 3000;
const port = 8090;
// 使用body-parser中间件来解析urlencoded格式的请求体 // 使用body-parser中间件来解析urlencoded格式的请求体
app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.get("/", (req, res) => { app.get("/", (req, res) => {
res.json({ res.json({
@ -15,13 +22,43 @@ app.get("/", (req, res) => {
}) })
app.post('/do', (req, res) => { app.post('/do', (req, res) => {
// 获取请求体中的数据 // 获取请求体中的数据
const requestData = req.body; let requestData = {
"rev": -1
};
let func = ukey[ req.body.order ]
if ( func ){
try {
let ret = func(req.body)
requestData = Object.assign(ret, {
"rev": 0
})
} catch ( e ) {
console.error( e )
requestData.msg = e;
}
}
// 设置响应类型为application/x-json // 设置响应类型为application/x-json
res.setHeader('Content-Type', 'application/x-json'); // 注意application/x-json不是标准MIME类型通常使用application/json res.setHeader('Content-Type', 'application/x-json'); // 注意application/x-json不是标准MIME类型通常使用application/json
// 将请求的数据返回为json格式的响应体 // 将请求的数据返回为json格式的响应体
res.json(requestData); res.json(requestData);
}); });
(async () => {
try {
await killPortProcess(port);
} catch (e) {
}
app.listen(port, () => { app.listen(port, () => {
console.log(`Server is running on port ${port}`); console.log(`Server is running on port ${port}`);
}); });
})();