Created
April 4, 2018 10:29
-
-
Save luchenqun/f58d2aefa222555ed29b933b41cbb350 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var keythereum = require("keythereum"); | |
| var path = require("path"); | |
| var fs = require("fs-extra"); | |
| var createKeccakHash = require("keccak/js"); | |
| var os = require('os'); | |
| var secp256k1 = require("secp256k1/elliptic"); | |
| var ffi = require('ffi'); | |
| var ref = require('ref'); | |
| var sha3 = require('crypto-js/sha3'); | |
| var params = { | |
| keyBytes: 32, | |
| ivBytes: 16 | |
| }; | |
| var options = { | |
| kdf: "pbkdf2", | |
| cipher: "aes-128-ctr", | |
| kdfparams: { | |
| c: 1, | |
| dklen: 32, | |
| prf: "hmac-sha256" | |
| } | |
| }; | |
| const DEFAULT_PATH = path.join(os.homedir(), 'keystores'); | |
| var ukey = null; | |
| var dwordPoint = ref.refType(ref.types.ulong); | |
| var uint64Point = ref.refType(ref.types.uint64); | |
| var boolPoint = ref.refType(ref.types.bool); | |
| if (os.platform() === 'win32') { | |
| var dllPath = null; | |
| if (os.platform() === 'win32') { | |
| if (os.arch() === 'x64') { | |
| dllPath = path.join("c:", "Windows", "System32", "WatchDataV5", "Juzhen CSP v1.0", "WDJuZhenAPI.dll"); | |
| } else { | |
| dllPath = path.join("c:", "Windows", "SysWOW64", "WatchDataV5", "Juzhen CSP v1.0", "WDJuZhenAPI.dll"); | |
| } | |
| } | |
| if (fs.existsSync(dllPath)) { | |
| ukey = ffi.Library(dllPath, { | |
| 'J_BC_WD_EnumDevice': ['int', ['string', dwordPoint]], // 01 | |
| 'J_BC_WD_OpenDevice': ['int', ['string', uint64Point]], // 02 | |
| 'J_BC_WD_CloseDevice': ['int', ['uint64']], // 03 | |
| 'J_BC_WD_FormatDevice': ['int', ['uint64', 'string']], // 04 | |
| 'J_BC_WD_IsDefaultPin': ['int', ['uint64', 'int', boolPoint]], // 05 | |
| 'J_BC_WD_VerifyPin': ['int', ['uint64', 'ulong', 'string', dwordPoint]], // 06 | |
| 'J_BC_WD_ChangePin': ['int', ['uint64', 'ulong', 'string', 'string', dwordPoint]], // 07 | |
| 'J_BC_WD_RSAGenKey': ['int', ['uint64']], // 08 | |
| 'J_BC_WD_ECCGenKey': ['int', ['uint64']], // 09 | |
| 'J_BC_WD_RSAGetPubKey': ['int', ['uint64', 'string', dwordPoint]], // 10 | |
| 'J_BC_WD_ECCGetPubKey': ['int', ['uint64', 'string', dwordPoint]], // 11 | |
| 'J_BC_WD_ImportRSACert': ['int', ['uint64', 'string']], // 12 | |
| 'J_BC_WD_ExPortRSACert': ['int', ['uint64', 'string', dwordPoint]], // 13 | |
| 'J_BC_WD_RSAEncrypt': ['int', ['uint64', 'string', 'int', 'string', dwordPoint]], // 14 | |
| 'J_BC_WD_RSASign': ['int', ['uint64', 'int', 'string', 'int', 'string', dwordPoint]], // 15 | |
| 'J_BC_WD_ECCSign': ['int', ['uint64', 'string', 'int', 'string', 'int', 'string', dwordPoint]], // 16 | |
| 'J_BC_WD_RSAVerifySign': ['int', ['uint64', 'int', 'string', 'int', 'string']], // 17 | |
| 'J_BC_WD_ECCVerifySign': ['int', ['uint64', 'string']], // 18 | |
| 'J_BC_BE_Enc': ['int', ['uint64', 'string', 'int', 'int', 'string', 'string', dwordPoint]], // 19 | |
| 'J_BC_BE_Dec': ['int', ['uint64', 'string', 'int', 'int', 'string', dwordPoint]], // 20 | |
| 'J_BC_GS_CheckKeyPair': ['int', ['uint64']], // 21 | |
| 'J_BC_GS_ImportMPubKey': ['int', ['uint64', 'string', 'int']], // 22 | |
| 'J_BC_GS_ImportUPriKey': ['int', ['uint64', 'string', 'int']], // 23 | |
| 'J_BC_GS_Sign': ['int', ['uint64', 'string', 'int', 'string', dwordPoint]], // 24 | |
| 'J_BC_GS_Verify': ['int', ['uint64', 'string', 'int', 'string', 'int']], // 25 | |
| 'J_BC_WD_TradeSignProtect': ['int', ['uint64', 'string', 'int', 'string', 'int', 'int', 'string', 'string', dwordPoint]], // 26 | |
| 'WDScardEncrypt_ECIES': ['int', ['uint64', 'string', 'int', 'string', dwordPoint]], // 27 | |
| 'WDScardDecrypt_ECIES': ['int', ['uint64', 'string', 'int', 'string', dwordPoint]], // 28 | |
| 'J_BC_WD_WriteData': ['int', ['uint64', 'string', 'int']], // 29 | |
| 'J_BC_WD_ReadData': ['int', ['uint64', 'string', dwordPoint]], // 30 | |
| 'WDScardGenKey_PAI': ['int', ['uint64', 'int']], // 31 | |
| 'WDScardGetPubKeyn_PAI': ['int', ['uint64', 'string', dwordPoint]], // 32 | |
| 'WDScardEncryption_PAI': ['int', ['uint64', 'string', 'int', 'string', dwordPoint]], // 33 | |
| 'WDScardDecryption_PAI': ['int', ['uint64', 'string', 'int', 'string', dwordPoint]], // 34 | |
| 'WDScardHomAdd_PAI': ['int', ['uint64', 'string', 'int', 'string', 'int', 'string', dwordPoint]], // 35 | |
| }); | |
| } else { | |
| console.error('WatchDataV5 not exit!') | |
| } | |
| } | |
| function keccak256(buffer) { | |
| return createKeccakHash("keccak256").update(buffer).digest(); | |
| } | |
| function isFunction(f) { | |
| return typeof f === "function"; | |
| } | |
| function c(err) { | |
| switch (err) { | |
| case null: return -100; | |
| case 1: return 0; | |
| case 0: return 1; | |
| default: return err; | |
| } | |
| } | |
| function getBLen(str) { | |
| var len = 0; | |
| for (var i = 0; i < str.length; i++) { | |
| var c = str.charCodeAt(i); | |
| if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) { | |
| len++; | |
| } else { | |
| len += 3; | |
| } | |
| } | |
| return len; | |
| } | |
| module.exports = { | |
| // 01 J_BC_WD_EnumDevice ( OUT BYTE*pbNameList, OUT DWORD* pdwSizeLen); | |
| ukeyEnumDevice: function (cb) { | |
| var pbNameList = Buffer.alloc(512); | |
| var pdwSizeLen = ref.alloc('ulong'); | |
| pdwSizeLen.writeUInt32LE(pbNameList.length); | |
| var err = c(ukey && ukey.J_BC_WD_EnumDevice(pbNameList, pdwSizeLen)); | |
| if (err === 0) { | |
| pdwSizeLen = pdwSizeLen.readUInt32LE(); | |
| pbNameList = pbNameList.toString('ascii', 0, pdwSizeLen); | |
| pbNameList = pbNameList.split("\u0000"); | |
| pbNameList = pbNameList.filter((name) => name != ''); | |
| } | |
| var ret = { | |
| err: err, | |
| pbNameList: pbNameList, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 02 J_BC_WD_OpenDevice (IN BYTE* pbDevSN,OUT HANDLE* phDev); | |
| ukeyOpenDevice: function (pbDevSN, cb) { | |
| var phDev = ref.alloc('uint64'); | |
| phDev.writeUInt64LE(0); | |
| var err = c(ukey && ukey.J_BC_WD_OpenDevice(pbDevSN, phDev)); | |
| if (err === 0) { | |
| phDev = phDev.readUInt64LE(); | |
| } | |
| var ret = { | |
| err: err, | |
| phDev: phDev, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 03 J_BC_WD_CloseDevice(IN HANDLE hDev); | |
| ukeyCloseDevice: function (hDev, cb) { | |
| var err = c(ukey && ukey.J_BC_WD_CloseDevice(hDev)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 04 J_BC_WD_FormatDevice(IN HANDLE hDev,IN BYTE *pbSoPin); | |
| ukeyFormatDevice: function (hDev, pbSoPin, cb) { | |
| var err = c(ukey && ukey.J_BC_WD_FormatDevice(hDev, pbSoPin)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 05 J_BC_WD_IsDefaultPin (IN HANDLE hDev,IN DWORD dwPinType,OUT BOOL* pbDefaultPin); | |
| ukeyIsDefaultPin: function (hDev, dwPinType, cb) { | |
| var pbDefaultPin = ref.alloc('bool'); | |
| var err = c(ukey && ukey.J_BC_WD_IsDefaultPin(hDev, dwPinType, pbDefaultPin)); | |
| if (err === 0) { | |
| pbDefaultPin = Boolean(parseInt(pbDefaultPin.toString('hex'))); | |
| } | |
| var ret = { | |
| err: err, | |
| pbDefaultPin: pbDefaultPin, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 06 J_BC_WD_VerifyPin (IN HANDLE hDev,IN DWORD dwPinType,IN BYTE *pbUserPin,OUT DWORD *pdwRetryCount); | |
| ukeyVerifyPin: function (hDev, dwPinType, pbUserPin, cb) { | |
| var pdwRetryCount = ref.alloc('ulong'); | |
| var err = c(ukey && ukey.J_BC_WD_VerifyPin(hDev, dwPinType, pbUserPin, pdwRetryCount)); | |
| if (err != 0) { | |
| pdwRetryCount = pdwRetryCount.readUInt32LE(); | |
| } | |
| var ret = { | |
| err: err, | |
| pdwRetryCount: pdwRetryCount, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 07 J_BC_WD_ChangePin (IN HANDLE hDev,IN DWORD dwPinType,IN BYTE *pbOldPin,IN BYTE *pbNewPin,OUT DWORD *pdwRetryCount) | |
| ukeyChangePin: function (hDev, dwPinType, pbOldPin, pbNewPin, cb) { | |
| var pdwRetryCount = ref.alloc('ulong'); | |
| var err = c(ukey && ukey.J_BC_WD_ChangePin(hDev, dwPinType, pbOldPin, pbNewPin, pdwRetryCount)); | |
| if (err != 0) { | |
| pdwRetryCount = pdwRetryCount.readUInt32LE(); | |
| } | |
| var ret = { | |
| err: err, | |
| pdwRetryCount: pdwRetryCount, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 08 J_BC_WD_RSAGenKey (IN HANDLE hDev) | |
| ukeyRSAGenKey: function (hDev, cb) { | |
| var err = c(ukey && ukey.J_BC_WD_RSAGenKey(hDev)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 09 J_BC_WD_ECCGenKey (IN HANDLE hDev) | |
| ukeyECCGenKey: function (hDev, cb) { | |
| var err = c(ukey && ukey.J_BC_WD_ECCGenKey(hDev)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 10 J_BC_WD_RSAGetPubKey (IN HANDLE hDev, OUT BYTE *pbPubKey, OUT DWORD *pdwPubKeyLen) | |
| ukeyRSAGetPubKey: function (hDev, cb) { | |
| var pbPubKey = Buffer.alloc(512); | |
| var pdwPubKeyLen = ref.alloc('ulong'); | |
| pdwPubKeyLen.writeUInt32LE(pbPubKey.length); | |
| var err = c(ukey && ukey.J_BC_WD_RSAGetPubKey(hDev, pbPubKey, pdwPubKeyLen)); | |
| if (err === 0) { | |
| pdwPubKeyLen = pdwPubKeyLen.readUInt32LE(); | |
| pbPubKey = pbPubKey.toString('hex', 0, pdwPubKeyLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbPubKey: pbPubKey, | |
| // pdwPubKeyLen: pdwPubKeyLen, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 11 J_BC_WD_ECCGetPubKey (IN HANDLE hDev, OUT BYTE *pbPubKey, OUT DWORD *pdwPubKeyLen); | |
| ukeyECCGetPubKey: function (hDev, cb) { | |
| var pbPubKey = Buffer.alloc(512); | |
| var pdwPubKeyLen = ref.alloc('ulong'); | |
| pdwPubKeyLen.writeUInt32LE(pbPubKey.length); | |
| var err = c(ukey && ukey.J_BC_WD_ECCGetPubKey(hDev, pbPubKey, pdwPubKeyLen)); | |
| if (err === 0) { | |
| pdwPubKeyLen = pdwPubKeyLen.readUInt32LE(); | |
| pbPubKey = pbPubKey.toString('hex', 0, pdwPubKeyLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbPubKey: pbPubKey, | |
| // pdwPubKeyLen: pdwPubKeyLen, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| ukeyECCAddress: function (hDev, cb) { | |
| var r = this.ukeyECCGetPubKey(hDev); | |
| var ret = { | |
| err: r.err, | |
| address: null, | |
| } | |
| if (r.err === 0) { | |
| ret.address = '0x' + createKeccakHash("keccak256").update(Buffer.from(r.pbPubKey, 'hex')).digest().toString('hex').slice(-40); | |
| } | |
| isFunction(cb) && cb(ret.err, ret); | |
| return ret; | |
| }, | |
| // 12 J_BC_WD_ImportRSACert(IN HANDLE hDev, IN BYTE *pbCert) | |
| ukeyImportRSACert: function (hDev, pbCert, cb) { | |
| var err = c(ukey && ukey.J_BC_WD_ImportRSACert(hDev, pbCert)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 13 J_BC_WD_ExPortRSACert(IN HANDLE hDev, OUT BYTE *pbCert,OUT DWORD *pdwCertLen); | |
| ukeyExPortRSACert: function (hDev, cb) { | |
| var pbCert = Buffer.alloc(128); | |
| var pdwCertLen = ref.alloc('ulong'); | |
| pdwCertLen.writeUInt32LE(pbCert.length); | |
| var err = c(ukey && ukey.J_BC_WD_ExPortRSACert(hDev, pbCert, pdwCertLen)); | |
| if (err === 0) { | |
| pdwCertLen = pdwCertLen.readUInt32LE(); | |
| pbCert = pbCert.toString('hex', 0, pdwCertLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbCert: pbCert, | |
| // pdwCertLen: pdwCertLen, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 14 J_BC_WD_RSAEncrypt(IN HANDLE hDev, IN BYTE *pbData, IN DWORD dwDataLen, OUT BYTE*pbCipher, OUT DWORD* pdwCipherLen) | |
| ukeyRSAEncrypt: function (hDev, pbData, cb) { | |
| var dwDataLen = pbData.length; | |
| var pbCipher = Buffer.alloc(512); | |
| var pdwCipherLen = ref.alloc('ulong'); | |
| pdwCipherLen.writeUInt32LE(pbCipher.length); | |
| var err = c(ukey && ukey.J_BC_WD_RSAEncrypt(hDev, pbData, dwDataLen, pbCipher, pdwCipherLen)); | |
| if (err === 0) { | |
| pdwCipherLen = pdwCipherLen.readUInt32LE(); | |
| pbCipher = pbCipher.toString('hex', 0, pdwCipherLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbCipher: pbCipher, | |
| // pdwCipherLen: pdwCipherLen, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 15 J_BC_WD_RSASign (IN HANDLE hDev, IN DWORD dwHashAlg, IN BYTE* pbData, IN DWORD dwDataLen, OUT BYTE* pbSign, OUT DWORD* pdwSignLen) | |
| ukeyRSASign: function (hDev, dwHashAlg, pbData, cb) { | |
| var dwDataLen = pbData.length; | |
| var pbSign = Buffer.alloc(512); | |
| var pdwSignLen = ref.alloc('ulong'); | |
| pdwSignLen.writeUInt32LE(pbSign.length); | |
| var err = c(ukey && ukey.J_BC_WD_RSASign(hDev, dwHashAlg, pbData, dwDataLen, pbSign, pdwSignLen)); | |
| if (err === 0) { | |
| pdwSignLen = pdwSignLen.readUInt32LE(); | |
| pbSign = pbSign.toString('hex', 0, pdwSignLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbSign: pbSign, | |
| // pdwSignLen: pdwSignLen, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 16 J_BC_WD_ECCSign (IN HANDLE hDev, IN BYTE* pbMsgRlp,IN DWORD dwMsgRlpLen, IN BYTE* pbShowData,IN DWORD dwShowLen, OUT BYTE*pbSignRlp, OUT DWORD*pdwSignLen); | |
| ukeyECCSign: function (hDev, pbMsgRlp, pbShowData, cb) { | |
| var pbMsgRlp = Buffer.from(pbMsgRlp, 'hex'); | |
| var dwMsgRlpLen = pbMsgRlp.length; | |
| var dwShowLen = getBLen(pbShowData); | |
| var pbSignRlp = Buffer.alloc(pbMsgRlp.length + 1024); | |
| var pdwSignLen = ref.alloc('ulong'); | |
| pdwSignLen.writeUInt32LE(pbSignRlp.length); | |
| var err = c(ukey && ukey.J_BC_WD_ECCSign(hDev, pbMsgRlp, dwMsgRlpLen, pbShowData, dwShowLen, pbSignRlp, pdwSignLen)); | |
| if (err === 0) { | |
| pdwSignLen = pdwSignLen.readUInt32LE(); | |
| pbSignRlp = pbSignRlp.toString('hex', 0, pdwSignLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbSignRlp: pbSignRlp, | |
| // pdwSignLen: pdwSignLen, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 17 J_BC_WD_RSAVerifySign(IN HANDLE hDev, IN DWORD dwHashAlg, IN BYTE* pbData, IN DWORD dwDataLen, IN BYTE* pbSign); 注释跟头文件生命不一致 | |
| ukeyRSAVerifySign: function (hDev, dwHashAlg, pbData, pbSign, cb) { | |
| dwDataLen = pbData.length; | |
| pbSign = Buffer.from(pbSign, 'hex'); | |
| var err = c(ukey && ukey.J_BC_WD_RSAVerifySign(hDev, dwHashAlg, pbData, dwDataLen, pbSign)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 18 J_BC_WD_ECCVerifySign(IN HANDLE hDev, IN BYTE* pbSignRlp) | |
| ukeyECCVerifySign: function (hDev, pbSignRlp, cb) { | |
| pbSignRlp = Buffer.from(pbSignRlp, 'hex'); | |
| var err = c(ukey && ukey.J_BC_WD_ECCVerifySign(hDev, pbSignRlp)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 19 J_BC_BE_Enc(IN HANDLE hDev, IN BYTE*pbMessage, IN DWORD dwMessage_Len, IN DWORD dwGroupNum, IN BYTE*pbGroup_PubKey, OUT BYTE*pbCipherText, OUT DWORD *pdwCipherText_Len) | |
| ukeyEnc: function (hDev, pbMessage, dwGroupNum, pbGroup_PubKey, cb) { | |
| pbMessage = Buffer.from(pbMessage, 'hex'); | |
| var dwMessage_Len = pbMessage.length; | |
| pbGroup_PubKey = Buffer.from(pbGroup_PubKey, 'hex'); | |
| var pbCipherText = Buffer.alloc(1024); | |
| var pdwCipherText_Len = ref.alloc('ulong'); | |
| pdwCipherText_Len.writeUInt32LE(pbCipherText.length); | |
| var err = c(ukey && ukey.J_BC_BE_Enc(hDev, pbMessage, dwMessage_Len, dwGroupNum, pbGroup_PubKey, pbCipherText, pdwCipherText_Len)); | |
| if (err === 0) { | |
| pdwCipherText_Len = pdwCipherText_Len.readUInt32LE(); | |
| pbCipherText = pbCipherText.toString('hex', 0, pdwCipherText_Len); | |
| } | |
| var ret = { | |
| err: err, | |
| pbCipherText: pbCipherText, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 20 J_BC_BE_Dec(IN HANDLE hDev, IN BYTE*pbCipherText, IN DWORD dwCipherText_Len, IN DWORD dwGroupNum, OUT BYTE*pbMessage, OUT DWORD*pdwMessage_Len) | |
| ukeyDec: function (hDev, pbCipherText, dwGroupNum, cb) { | |
| pbCipherText = Buffer.from(pbCipherText, 'hex'); | |
| var dwCipherText_Len = pbCipherText.length; | |
| var pbMessage = Buffer.alloc(1024); | |
| var pdwMessage_Len = ref.alloc('ulong'); | |
| pdwMessage_Len.writeUInt32LE(pbMessage.length); | |
| var err = c(ukey && ukey.J_BC_BE_Dec(hDev, pbCipherText, dwCipherText_Len, dwGroupNum, pbMessage, pdwMessage_Len)); | |
| if (err === 0) { | |
| pdwMessage_Len = pdwMessage_Len.readUInt32LE(); | |
| pbMessage = pbMessage.toString('hex', 0, pdwMessage_Len); | |
| } | |
| var ret = { | |
| err: err, | |
| pbMessage: pbMessage, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 21 J_BC_GS_CheckKeyPair(IN HANDLE hDev) | |
| ukeyCheckKeyPair: function (hDev, cb) { | |
| var err = c(ukey && ukey.J_BC_GS_CheckKeyPair(hDev)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 22 J_BC_GS_ImportMPubKey(IN HANDLE hDev, IN BYTE* pbMPubKey,IN DWORD dwMPubKey) | |
| ukeyImportMPubKey: function (hDev, pbMPubKey, cb) { | |
| pbMPubKey = Buffer.from(pbMPubKey, 'hex'); | |
| var dwMPubKey = pbMPubKey.length; | |
| var err = c(ukey && ukey.J_BC_GS_ImportMPubKey(hDev, pbMPubKey, dwMPubKey)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 23 J_BC_GS_ImportUPriKey(IN HANDLE hDev, IN BYTE *pbUPriKey,IN DWORD dwUPriKey) | |
| ukeyImportUPriKey: function (hDev, pbUPriKey, cb) { | |
| var ret = this.ukeyWDScardEncryptECIES(hDev, pbUPriKey); | |
| var err = ret.err; | |
| var pbEncryptedData = null; | |
| if (ret.err === 0) { | |
| pbEncryptedData = ret.pbEncryptedData; | |
| pbUPriKey = Buffer.from(ret.pbEncryptedData, 'hex'); | |
| var dwUPriKey = pbUPriKey.length; | |
| var err = c(ukey && ukey.J_BC_GS_ImportUPriKey(hDev, pbUPriKey, dwUPriKey)); | |
| } | |
| var ret1 = { | |
| err: err, | |
| pbEncryptedData: pbEncryptedData, | |
| } | |
| isFunction(cb) && cb(err, ret1); | |
| return ret1; | |
| }, | |
| // 24 J_BC_GS_Sign(IN HANDLE hDev, IN BYTE* pbHash, IN DWORD dwHash, OUT BYTE*pbSign, OUT DWORD* pdwSignLen) | |
| ukeyGSSign: function (hDev, pbHash, cb) { | |
| pbHash = sha3(pbHash, { outputLength: 256 }).toString(); | |
| pbHash = Buffer.from(pbHash, 'hex'); | |
| var dwHash = pbHash.length; | |
| var pbSign = Buffer.alloc(512); | |
| var pdwSignLen = ref.alloc('ulong'); | |
| pdwSignLen.writeUInt32LE(pbSign.length); | |
| var err = c(ukey && ukey.J_BC_GS_Sign(hDev, pbHash, dwHash, pbSign, pdwSignLen)); | |
| if (err === 0) { | |
| pdwSignLen = pdwSignLen.readUInt32LE(); | |
| pbSign = pbSign.toString('hex', 0, pdwSignLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbSign: pbSign, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 25 J_BC_GS_Verify(IN HANDLE hDev, IN BYTE* pbHash, IN DWORD dwHash, IN BYTE* pbSign, IN DWORD dwSignLen) | |
| ukeyGSVerify: function (hDev, pbHash, pbSign, cb) { | |
| pbHash = sha3(pbHash, { outputLength: 256 }).toString(); | |
| pbHash = Buffer.from(pbHash, 'hex'); | |
| var dwHash = pbHash.length; | |
| pbSign = Buffer.from(pbSign, 'hex'); | |
| var pdwSignLen = pbSign.length; | |
| var err = c(ukey && ukey.J_BC_GS_Verify(hDev, pbHash, dwHash, pbSign, pdwSignLen)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 26 J_BC_WD_TradeSignProtect(IN HANDLE hDev, IN BYTE *pbMsg, IN DWORD dwMsg, IN BYTE* pbShowData, IN DWORD dwShowLen, IN DWORD dwGroupNum, IN BYTE *pbGroup_PubKey, OUT BYTE *pbSign, OUT DWORD *pdwSignLen) | |
| ukeyTradeSignProtect: function (hDev, pbMsg, pbShowData, dwGroupNum, pbGroup_PubKey, cb) { | |
| pbMsg = Buffer.from(pbMsg, 'hex'); | |
| var dwMsg = pbMsg.length; | |
| var dwShowLen = getBLen(pbShowData); | |
| pbGroup_PubKey = Buffer.from(pbGroup_PubKey, 'hex'); | |
| var pbSign = Buffer.alloc(1024); | |
| var pdwSignLen = ref.alloc('ulong'); | |
| pdwSignLen.writeUInt32LE(pbSign.length); | |
| var err = c(ukey && ukey.J_BC_WD_TradeSignProtect(hDev, pbMsg, dwMsg, pbShowData, dwShowLen, dwGroupNum, pbGroup_PubKey, pbSign, pdwSignLen)); | |
| if (err === 0) { | |
| pdwSignLen = pdwSignLen.readUInt32LE(); | |
| pbSign = pbSign.toString('hex', 0, pdwSignLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbSign: pbSign, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 27 WDScardEncrypt_ECIES(IN HANDLE hDev, IN LPBYTE pbData, IN DWORD dwDataLen, OUT LPBYTE pbEncryptedData, OUT LPDWORD pdwEncryptedDataLen); | |
| ukeyWDScardEncryptECIES: function (hDev, pbData, cb) { | |
| pbData = Buffer.from(pbData, 'hex'); | |
| var dwDataLen = pbData.length; | |
| var pbEncryptedData = Buffer.alloc(1024); | |
| var pdwEncryptedDataLen = ref.alloc('ulong'); | |
| pdwEncryptedDataLen.writeUInt32LE(pbEncryptedData.length); | |
| var err = c(ukey && ukey.WDScardEncrypt_ECIES(hDev, pbData, dwDataLen, pbEncryptedData, pdwEncryptedDataLen)); | |
| if (err === 0) { | |
| pdwEncryptedDataLen = pdwEncryptedDataLen.readUInt32LE(); | |
| pbEncryptedData = pbEncryptedData.toString('hex', 0, pdwEncryptedDataLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbEncryptedData: pbEncryptedData, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 28 WDScardDecrypt_ECIES(IN HANDLE hDev, IN LPBYTE pbEncryptedData, IN DWORD dwEncryptedDataLen, OUT LPBYTE pbDecryptedData, OUT PDWORD pdwDecryptedDataLen) | |
| ukeyWDScardDecryptECIES: function (hDev, pbEncryptedData, cb) { | |
| pbEncryptedData = Buffer.from(pbEncryptedData, 'hex'); | |
| var dwEncryptedDataLen = pbEncryptedData.length; | |
| var pbDecryptedData = Buffer.alloc(1024); | |
| var pdwDecryptedDataLen = ref.alloc('ulong'); | |
| pdwDecryptedDataLen.writeUInt32LE(pbDecryptedData.length); | |
| var err = c(ukey && ukey.WDScardDecrypt_ECIES(hDev, pbEncryptedData, dwEncryptedDataLen, pbDecryptedData, pdwDecryptedDataLen)); | |
| if (err === 0) { | |
| pdwDecryptedDataLen = pdwDecryptedDataLen.readUInt32LE(); | |
| pbDecryptedData = pbDecryptedData.toString('hex', 0, pdwDecryptedDataLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbDecryptedData: pbDecryptedData, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 29 J_BC_WD_WriteData(IN HANDLE hDev, IN LPBYTE pbData, IN DWORD dwDataLen) | |
| ukeyWriteData: function (hDev, pbData, cb) { | |
| var dwDataLen = pbData.length; | |
| var err = c(ukey && ukey.J_BC_WD_WriteData(hDev, pbData, dwDataLen)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 30 J_BC_WD_ReadData(IN HANDLE hDev, OUT LPBYTE pbData, OUT DWORD *pdwDataLen) | |
| ukeyReadData: function (hDev, cb) { | |
| var pbData = Buffer.alloc(4096); | |
| var pdwDataLen = ref.alloc('ulong'); | |
| pdwDataLen.writeUInt32LE(pbData.length); | |
| var err = c(ukey && ukey.J_BC_WD_ReadData(hDev, pbData, pdwDataLen)); | |
| if (err === 0) { | |
| pdwDataLen = pdwDataLen.readUInt32LE(); | |
| pbData = pbData.toString('ascii', 0, pdwDataLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbData: pbData, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 31 WDScardGenKey_PAI(IN HANDLE hDev,IN DWORD dwKeyLen) | |
| ukeyWDScardGenKeyPAI: function (hDev, cb) { | |
| var dwKeyLen = 128; | |
| var err = c(ukey && ukey.WDScardGenKey_PAI(hDev, dwKeyLen)); | |
| var ret = { | |
| err: err, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 32 WDScardGetPubKeyn_PAI(IN HANDLE hDev,OUT LPBYTE pbPubKey_n,OUT DWORD *dwPubKeyLen); | |
| ukeyWDScardGetPubKeynPAI: function (hDev, cb) { | |
| var pbPubKey_n = Buffer.alloc(1024); | |
| var dwPubKeyLen = ref.alloc('ulong'); | |
| dwPubKeyLen.writeUInt32LE(pbPubKey_n.length); | |
| var err = c(ukey && ukey.WDScardGetPubKeyn_PAI(hDev, pbPubKey_n, dwPubKeyLen)); | |
| if (err === 0) { | |
| dwPubKeyLen = dwPubKeyLen.readUInt32LE(); | |
| pbPubKey_n = pbPubKey_n.toString('hex', 0, dwPubKeyLen); | |
| } | |
| var key = new String(pbPubKey_n); | |
| var ignore = 2; | |
| var pubLen = parseInt('0x' + key[ignore] + key[ignore+1]) * 2; | |
| var publicKey = key.substr(4, pubLen); | |
| key = key.substr(2 + ignore + pubLen); | |
| var priLen = parseInt('0x' + key[ignore] + key[ignore+1]) * 2; | |
| var privateKey = key.substr(4, priLen); | |
| var ret = { | |
| err: err, | |
| pbPubKey_n: pbPubKey_n, | |
| privateKey: privateKey, | |
| publicKey: publicKey, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 33 WDScardEncryption_PAI(IN HANDLE hDev, IN LPBYTE pbMsg, IN DWORD dwMsgLen, OUT LPBYTE pbCipher, OUT LPDWORD pdwCipherLen); | |
| ukeyWDScardEncryptionPAI: function (hDev, pbMsg, cb) { | |
| if (typeof pbMsg === 'string') { | |
| pbMsg = Buffer.from(pbMsg, 'hex'); | |
| console.log(pbMsg.readUInt32LE(pbMsg.length - 4)); | |
| } else { | |
| var num = pbMsg; | |
| pbMsg = Buffer.alloc(128); | |
| pbMsg.writeUInt32BE(num, pbMsg.length - 4); | |
| } | |
| var dwMsgLen = pbMsg.length; | |
| var pbCipher = Buffer.alloc(1024); | |
| var pdwCipherLen = ref.alloc('ulong'); | |
| pdwCipherLen.writeUInt32LE(pbCipher.length); | |
| var err = c(ukey && ukey.WDScardEncryption_PAI(hDev, pbMsg, dwMsgLen, pbCipher, pdwCipherLen)); | |
| if (err === 0) { | |
| pdwCipherLen = pdwCipherLen.readUInt32LE(); | |
| pbCipher = pbCipher.toString('hex', 0, pdwCipherLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbCipher: pbCipher, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 34 WINAPI WDScardDecryption_PAI(IN HANDLE hDev, IN LPBYTE pbCipher, IN DWORD dwCipherLen, OUT LPBYTE pbMsg, OUT LPDWORD pdwMsgLen); | |
| ukeyWDScardDecryptionPAI: function (hDev, pbCipher, cb) { | |
| pbCipher = Buffer.from(pbCipher, 'hex'); | |
| var dwCipherLen = pbCipher.length; | |
| var pbMsg = Buffer.alloc(16); | |
| var dwMsgLen = ref.alloc('ulong'); | |
| dwMsgLen.writeUInt32LE(pbMsg.length); | |
| var err = c(ukey && ukey.WDScardDecryption_PAI(hDev, pbCipher, dwCipherLen, pbMsg, dwMsgLen)); | |
| if (err === 0) { | |
| dwMsgLen = dwMsgLen.readUInt32LE(); | |
| // dwMsgLen = dwMsgLen > 4 ? 4 : dwMsgLen; | |
| var numBuffer = Buffer.alloc(4, 0); | |
| // console.log(pbMsg, numBuffer, numBuffer.length - dwMsgLen, 0, dwMsgLen); | |
| pbMsg.copy(numBuffer, numBuffer.length - dwMsgLen, 0, dwMsgLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbMsg: numBuffer.readUInt32BE(), | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 35 WDScardHomAdd_PAI(IN HANDLE hDev, IN LPBYTE pbCipherA, IN DWORD dwCipherALen, IN LPBYTE pbCipherB, IN DWORD dwCipherBLen, OUT LPBYTE pbResult, OUT LPDWORD pdwResultLen); | |
| ukeyWDScardHomAddPAI: function (hDev, pbCipherA, pbCipherB, cb) { | |
| pbCipherA = Buffer.from(pbCipherA, 'hex'); | |
| pbCipherB = Buffer.from(pbCipherB, 'hex'); | |
| var dwCipherALen = pbCipherA.length; | |
| var dwCipherBLen = pbCipherB.length; | |
| var pbResult = Buffer.alloc(1024); | |
| var pdwResultLen = ref.alloc('ulong'); | |
| pdwResultLen.writeUInt32LE(pbResult.length); | |
| var err = c(ukey && ukey.WDScardHomAdd_PAI(hDev, pbCipherA, dwCipherALen, pbCipherB, dwCipherBLen, pbResult, pdwResultLen)); | |
| if (err === 0) { | |
| pdwResultLen = pdwResultLen.readUInt32LE(); | |
| pbResult = pbResult.toString('hex', 0, pdwResultLen); | |
| } | |
| var ret = { | |
| err: err, | |
| pbResult: pbResult, | |
| } | |
| isFunction(cb) && cb(err, ret); | |
| return ret; | |
| }, | |
| // 以下为文件证书函数 | |
| browser: typeof process === "undefined" || !process.nextTick || Boolean(process.browser), | |
| setParams: function (_params) { | |
| params = _params; | |
| }, | |
| getParams: function () { | |
| return params; | |
| }, | |
| setOption: function (_options) { | |
| options = _options; | |
| }, | |
| getOption: function () { | |
| return options; | |
| }, | |
| createDk: function (cb) { | |
| err = 0; | |
| if (isFunction(cb)) { | |
| keythereum.create(this.getParams(), function (dk) { | |
| if (!dk) { | |
| err = 1; | |
| } | |
| cb(err, dk); | |
| }) | |
| } else { | |
| var dk = keythereum.create(this.getParams()); | |
| return dk; | |
| } | |
| }, | |
| // 获取key的文件名 | |
| generateKeystoreFilename: function (keyObject) { | |
| var now = new Date().getTime().toString(); | |
| filename = (keyObject.account || now) + '.json'; | |
| return filename; | |
| }, | |
| // 创建key | |
| createKey: function (account, username, password, cb) { | |
| var options = this.getOption(); | |
| var err = 0; | |
| if (isFunction(cb)) { | |
| this.createDk(function (_err, dk) { | |
| err = _err; | |
| if (!err) { | |
| keythereum.dump(password, dk.privateKey, dk.salt, dk.iv, options, function (keyObject) { | |
| if (keyObject) { | |
| keyObject.username = username; | |
| keyObject.account = account; | |
| keyObject.address = '0x' + keyObject.address; | |
| } else { | |
| err = 2; | |
| } | |
| cb(err, keyObject); | |
| }) | |
| } else { | |
| cb(err, keyObject); | |
| } | |
| }) | |
| } else { | |
| var dk = this.createDk(); | |
| var keyObject = keythereum.dump(password, dk.privateKey, dk.salt, dk.iv, options); | |
| keyObject.username = username; | |
| keyObject.account = account; | |
| keyObject.address = '0x' + keyObject.address; | |
| return keyObject; | |
| } | |
| }, | |
| // 导出key到文件 | |
| exportToFile: function (keyObject, keystore, outfileName, overWrite, cb) { | |
| keystore = keystore || DEFAULT_PATH; | |
| var err = 0; | |
| var outfileName = outfileName || this.generateKeystoreFilename(keyObject); | |
| var outpath = path.join(keystore, outfileName); | |
| var option = { spaces: 2 }; | |
| var fileExist = fs.existsSync(outpath); | |
| if (isFunction(cb)) { | |
| if (fileExist && (!overWrite)) { | |
| err = 2; | |
| cb(err, null); | |
| } else { | |
| fs.outputJson(outpath, keyObject, option, err => { | |
| if (!err) { | |
| cb(0, outpath) | |
| } | |
| }) | |
| } | |
| } else { | |
| if (fileExist && (!overWrite)) { | |
| return null; | |
| } else { | |
| fs.outputJsonSync(outpath, keyObject, option); | |
| return outpath; | |
| } | |
| } | |
| }, | |
| // 通过用户名,目录找到对应的key | |
| importFromAccount: function (account, keystore, cb) { | |
| keystore = keystore || DEFAULT_PATH; | |
| var filePath = path.join(keystore, account + '.json'); | |
| return this.importFromFilePath(filePath, cb); | |
| }, | |
| // 通过路径,找到对应的key | |
| importFromFilePath: function (filePath, cb) { | |
| if (isFunction(cb)) { | |
| fs.readJson(filePath, (err, keyObject) => { | |
| err = err ? 1 : 0; | |
| cb(err, keyObject); | |
| }) | |
| } else { | |
| var keyObject = null; | |
| try { | |
| keyObject = fs.readJsonSync(filePath); | |
| } catch (e) { | |
| } | |
| return keyObject; | |
| } | |
| }, | |
| // 获取某个目录下面的所有keys | |
| importFromDir: function (keystore, cb) { | |
| keystore = keystore || DEFAULT_PATH; | |
| var keyObjects = []; | |
| var self = this; | |
| if(!fs.existsSync(keystore)){ | |
| if (isFunction(cb)) { | |
| cb(2, keyObjects); | |
| } else { | |
| return keyObjects; | |
| } | |
| return; | |
| }; | |
| if (isFunction(cb)) { | |
| fs.readdir(keystore, function (err, files) { | |
| if (err || files.errno) { | |
| console.log('readFile ' + keystore + ' error: ', err || files.errno); | |
| cb(1, keyObjects); | |
| } else { | |
| files = files.filter((file) => file.endsWith('.json')); | |
| if (files.length === 0) { | |
| cb(0, keyObjects); | |
| } | |
| var readCount = 0; | |
| files.forEach(function (file, index) { | |
| var filePath = path.join(keystore, file); | |
| self.importFromFilePath(filePath, function (err, keyObject) { | |
| readCount++; | |
| if (err === 0) { | |
| keyObjects.push(keyObject) | |
| } | |
| if (readCount === files.length) { | |
| cb(0, keyObjects); | |
| } | |
| }); | |
| }); | |
| } | |
| }); | |
| } else { | |
| var files = fs.readdirSync(keystore); | |
| files = files.filter((file) => file.endsWith('.json')); | |
| files.forEach(function (file, index) { | |
| var filePath = path.join(keystore, file); | |
| var keyObject = self.importFromFilePath(filePath); | |
| if (keyObject) { | |
| keyObjects.push(keyObject); | |
| } | |
| }); | |
| return keyObjects; | |
| } | |
| }, | |
| // 重置key | |
| resetPassword: function (oldPassword, newPassword, keyObject, cb) { | |
| function deepClone(o){ | |
| return JSON.parse(JSON.stringify(o)); | |
| } | |
| var self = this; | |
| if (isFunction(cb)) { | |
| self.recover(oldPassword, keyObject, function (err, privateKey) { | |
| if (privateKey) { | |
| self.createDk(function (err, dk) { | |
| if (dk) { | |
| self.createKey(keyObject.account, keyObject.username, newPassword, function (err, newKeyObject) { | |
| var newKey = deepClone(keyObject); | |
| newKey.crypto = newKeyObject.crypto; | |
| cb(err, newKey); | |
| }) | |
| } else { | |
| cb(err, null); | |
| } | |
| }) | |
| } else { | |
| cb(err, null); | |
| } | |
| }); | |
| } else { | |
| var newKey = null; | |
| var privateKey = this.recover(oldPassword, keyObject); | |
| if (privateKey) { | |
| var dk = this.createDk(); | |
| var newKeyObject = this.createKey(keyObject.account, keyObject.username, newPassword); | |
| if (newKeyObject) { | |
| var newKey = deepClone(keyObject); | |
| newKey.crypto = newKeyObject.crypto; | |
| } | |
| } | |
| return newKey; | |
| } | |
| }, | |
| // 获取私钥privateKey | |
| recover: function (password, keyObject, cb) { | |
| var keyObjectCrypto, iv, salt, ciphertext, algo; | |
| var self = keythereum; | |
| var privateKey = ''; | |
| keyObjectCrypto = keyObject.Crypto || keyObject.crypto; | |
| function verifyAndDecrypt(derivedKey, salt, iv, ciphertext, algo) { | |
| var key; | |
| if (self.getMAC(derivedKey, ciphertext) !== keyObjectCrypto.mac) { | |
| return null; | |
| } | |
| if (keyObject.version === "1") { | |
| key = keccak256(derivedKey.slice(0, 16)).slice(0, 16); | |
| } else { | |
| key = derivedKey.slice(0, 16); | |
| } | |
| return self.decrypt(ciphertext, key, iv, algo); | |
| } | |
| iv = self.str2buf(keyObjectCrypto.cipherparams.iv); | |
| salt = self.str2buf(keyObjectCrypto.kdfparams.salt); | |
| ciphertext = self.str2buf(keyObjectCrypto.ciphertext); | |
| algo = keyObjectCrypto.cipher; | |
| if (keyObjectCrypto.kdf === "pbkdf2" && keyObjectCrypto.kdfparams.prf !== "hmac-sha256") { | |
| if (!isFunction(cb)) { | |
| return null; | |
| } else { | |
| cb(2, null); | |
| } | |
| } | |
| if (!isFunction(cb)) { | |
| privateKey = verifyAndDecrypt(self.deriveKey(password, salt, keyObjectCrypto), salt, iv, ciphertext, algo); | |
| if (privateKey) { | |
| privateKey = privateKey.toString('hex'); | |
| } | |
| return privateKey; | |
| } else { | |
| self.deriveKey(password, salt, keyObjectCrypto, function (derivedKey) { | |
| var err = 0; | |
| privateKey = verifyAndDecrypt(derivedKey, salt, iv, ciphertext, algo); | |
| if (!privateKey) { | |
| err = 1; | |
| } else { | |
| privateKey = privateKey.toString('hex'); | |
| } | |
| cb(err, privateKey); | |
| }); | |
| } | |
| }, | |
| // 获取公钥 | |
| getPublicKey: function (privateKey, cb) { | |
| var err = 0; | |
| if (typeof privateKey == 'string' && privateKey.constructor == String) { | |
| privateKey = Buffer.from(privateKey, 'hex'); | |
| } | |
| var publicKey = null; | |
| try { | |
| publicKey = secp256k1.publicKeyCreate(privateKey, false).slice(1); | |
| } catch (e) { | |
| err = 1; | |
| } | |
| if (publicKey) { | |
| publicKey = publicKey.toString('hex'); | |
| } | |
| if (isFunction(cb)) { | |
| cb(err, publicKey); | |
| } else { | |
| return publicKey; | |
| } | |
| }, | |
| // 导入keyObjects | |
| restoreKeys: function (srcDir, distDir, cb) { | |
| var err = 0; | |
| var copyFiles = []; | |
| distDir = distDir || DEFAULT_PATH; | |
| var option = { | |
| overwrite: false, | |
| } | |
| if(!fs.existsSync(srcDir)){ | |
| if (isFunction(cb)) { | |
| cb(1, []); | |
| } else { | |
| return []; | |
| } | |
| return; | |
| }; | |
| // 只拷贝一级目录且不存在目标路径的json文件。 | |
| var srcFiles = []; | |
| var distFiles = []; | |
| try { | |
| srcFiles = fs.readdirSync(srcDir).filter((file) => fs.lstatSync(path.join(srcDir, file)).isFile()); | |
| } catch (error) { } | |
| try { | |
| distFiles = fs.readdirSync(distDir).filter((file) => fs.lstatSync(path.join(distDir, file)).isFile()); | |
| } catch (error) { } | |
| srcFiles = srcFiles.filter((file) => file.endsWith('.json')); | |
| srcFiles = srcFiles.filter((file) => distFiles.indexOf(file) < 0); | |
| var copyCount = 0; | |
| if (isFunction(cb)) { | |
| var copyCount = 0; | |
| srcFiles.forEach((file, index) => { | |
| var srcFilePath = path.join(srcDir, file); | |
| var distFilePath = path.join(distDir, file); | |
| fs.copy(srcFilePath, distFilePath, option, function (err) { | |
| copyCount++; | |
| if (!err) { | |
| copyFiles.push(file); | |
| } | |
| if (copyCount === srcFiles.length) { | |
| cb(0, copyFiles); | |
| } | |
| }) | |
| }) | |
| if (srcFiles.length === 0) { | |
| cb(0, copyFiles); | |
| } | |
| } else { | |
| srcFiles.forEach((file, index) => { | |
| var srcFilePath = path.join(srcDir, file); | |
| var distFilePath = path.join(distDir, file); | |
| fs.copy(srcFilePath, distFilePath, option); | |
| copyFiles.push(file); | |
| }) | |
| return copyFiles; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment