From 00de726082ac3e37fd13826e8a7f82d3255dacd4 Mon Sep 17 00:00:00 2001 From: Cheney Date: Mon, 19 Aug 2024 18:01:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=8D=8F=E8=AE=AE=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 4 +- api.md | 1 - backend/src/FakeUKey.js | 265 ++++++++++++++++++++++++++++++++++++++++ backend/src/main.js | 47 ++++++- 4 files changed, 310 insertions(+), 7 deletions(-) delete mode 100644 api.md create mode 100644 backend/src/FakeUKey.js diff --git a/Readme.md b/Readme.md index 85fab62..093f8e9 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,8 @@ # Fake UKey -1. 暂时无法实现 UKEY 复制, 只能从初始化时就使用 Fake UKEY。 +1. 与渔翁 UKEY 协议完全兼容。内置 7 个虚拟 UKEY。 +2. 与渔翁 UKEY 驱动冲突。启动时会尝试强制剔除渔翁 UKEY,但是建议手工退出渔翁 UKEY 驱动。 +3. 暂时无法实现 UKEY 复制, 只能从初始化时就使用 Fake UKEY。 ## API diff --git a/api.md b/api.md deleted file mode 100644 index e941a91..0000000 --- a/api.md +++ /dev/null @@ -1 +0,0 @@ -enumDevByArray diff --git a/backend/src/FakeUKey.js b/backend/src/FakeUKey.js new file mode 100644 index 0000000..1ab0188 --- /dev/null +++ b/backend/src/FakeUKey.js @@ -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") + } + } + +} diff --git a/backend/src/main.js b/backend/src/main.js index 508a65c..69f4ef9 100644 --- a/backend/src/main.js +++ b/backend/src/main.js @@ -1,11 +1,18 @@ const express = require('express'); const bodyParser = require('body-parser'); +const ukey = require("./FakeUKey") +const cors = require('cors'); +const { killPortProcess } = require('kill-port-process'); + const app = express(); -const port = 3000; +// const port = 3000; +const port = 8090; // 使用body-parser中间件来解析urlencoded格式的请求体 app.use(bodyParser.urlencoded({ extended: true })); +app.use(cors()); + app.get("/", (req, res) => { res.json({ @@ -15,13 +22,43 @@ app.get("/", (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 res.setHeader('Content-Type', 'application/x-json'); // 注意application/x-json不是标准MIME类型,通常使用application/json // 将请求的数据返回为json格式的响应体 res.json(requestData); }); -app.listen(port, () => { - console.log(`Server is running on port ${port}`); -}); + +(async () => { + + try { + await killPortProcess(port); + } catch (e) { + + } + + + + app.listen(port, () => { + console.log(`Server is running on port ${port}`); + }); + +})(); +