795 字
4 分鐘
[ChtICToken.js] func sign 進行數位簽章 | 自然人憑證開發筆記
2024-01-08
無標籤

ChtICToken.js 中透過 sign 做數位簽章#

首頁 > 系列文 > 自然人憑證開發筆記

ChtICToken.js 版本:R1.0.0.57


sign(B64ToBeSign, UserPIN, HashAlg, RevFun, PKCSSignType, keyidb64, nonce, withSigningTime, withCardSN, checkValidity)#

sign 用於簽章,背後是呼叫API http://127.0.0.1:61161/sign,先了解前篇關於 /sign 的說明。接著來說明參數:

  1. B64ToBeSign 必填
    原文的 Base64
    ▶ 備註:等同 /sign 的 tbs 欄位,tbsEncoding 固定為 base64
  2. UserPIN 必填
    憑證卡 PIN 碼
    ▶ 備註:等同 /sign 的 pin 欄位
  3. HashAlg 必填
    Hash 演算法
    ▶ 選項:SHA1、SHA256
    ▶ 備註:等同 /sign 的 hashAlgorithm 欄位
  4. RevFun 必填
    Callback Function
  5. PKCSSignType 選填 簽章標準
    ▶ 預設:PKCS1
    ▶ 選項:PKCS1、PKCS7
    ▶ 備註:等同 /sign 的 signatureType 欄位
  6. keyidb64 選填 選擇憑證,憑證 ID 的 Base64
    ▶ 預設:U0lHTg== (SIGN,簽章憑證)
    ▶ 選項:U0lHTg== (SIGN,簽章憑證)、S0VZWA== (KEYX,加密憑證)
    ▶ 備註:等同 /sign 的 keyidb64 欄位
  7. nonce 選填
    一次性數字,增加簽章的隨機性,PKCS7 專用
    ▶ 預設:空字串
    ▶ 備註:等同 /sign 的 nonce欄位
  8. withSigningTime 選填 簽章值是否要包含簽章時間,PKCS7 專用
    ▶ 預設:true
    ▶ 選項:true、false
    ▶ 備註:等同 /sign 的 withSigningTime 欄位
  9. withCardSN 選填
    簽章值是否要包含卡號
    ▶ 預設:false
    ▶ 選項:true、false
    ▶ 備註:等同 /sign 的 withCardSN欄位
  10. checkValidity 選填 簽章前,是否檢查使用者系統時間在憑證有效期間內
    ▶ 預設:true
    ▶ 選項:true、false
    ▶ 備註:等同 /sign 的 checkValidity欄位

Response#

Callback funtion 中以 getICToken() 取得以下內容

{
"SmrtCrdID": ["<卡號>"],
"SlotID": ["InfoThink USB Reader 0"],
"SlotName": [],
"ActvSltID": ["0"],
"OldPIN": "",
"NewPIN": "",
"UID": "",
"CrdSys": "",
"KpMsg": "",
"exDynamicCreateFileInput": "",
"exDynamicReleaseFileInput": "",
"TBS": "VEJT",
"TbsEncoding": "base64",
"HashAlgorithm": "SHA256",
"PIN": "000000",
"FUN": "MakeSignature",
"SType": "PKCS1",
"RetObj": {
"RCode": "0",
"B64Signature": "<簽章值>",
"RMsg": "undefined"
},
"keyidb64": "__NotExistedTag__",
"nonce": "__NotExistedTag__",
"withSigningTime": "__NotExistedTag__",
"withCardSN": "__NotExistedTag__",
"checkValidity": "__NotExistedTag__"
}

原始碼#

ICToken.prototype.sign = function (
B64ToBeSign, UserPIN, HashAlg, RevFun, PKCSSignType,
keyidb64, nonce, withSigningTime, withCardSN, checkValidity
) {
if (typeof PKCSSignType === "undefined") PKCSSignType = "PKCS1";
if (typeof keyidb64 === "undefined") keyidb64 = "__NotExistedTag__";
if (typeof nonce === "undefined") nonce = "__NotExistedTag__";
if (typeof withSigningTime === "undefined")
withSigningTime = "__NotExistedTag__";
if (typeof withCardSN === "undefined") withCardSN = "__NotExistedTag__";
if (typeof checkValidity === "undefined") checkValidity = "__NotExistedTag__";
UserSign(
B64ToBeSign, encodeURIComponent(UserPIN), HashAlg, RevFun, PKCSSignType,
keyidb64, encodeURIComponent(nonce), encodeURIComponent(withSigningTime),
encodeURIComponent(withCardSN), encodeURIComponent(checkValidity), "none"
);
};
function UserSign(
B64ToBeSign, UserPIN, HashAlg, UrRevFUN, PKCSSignType, keyidb64,
nonce, withSigningTime, withCardSN, checkValidity, SignType
) {
var l_iRetCode = 0;
var l_B64Signature = "";
var l_vRMsg;
var l_vRetData;
if (typeof PKCSSignType === "undefined") PKCSSignType = "PKCS1";
if (typeof keyidb64 === "undefined") keyidb64 = "__NotExistedTag__";
if (typeof nonce === "undefined") nonce = "__NotExistedTag__";
if (typeof withSigningTime === "undefined")
withSigningTime = "__NotExistedTag__";
if (typeof withCardSN === "undefined") withCardSN = "__NotExistedTag__";
if (typeof checkValidity === "undefined") checkValidity = "__NotExistedTag__";
if (PKCSSignType == "PKCS7") {
InToken.SType = "PKCS7";
} else {
//Default: "PKCS1"
}
if (SignType.localeCompare("Cryp") == 0) {
InToken.FUN = "umakeSig";
GARevFun.FUN = "StSgn";
} else {
InToken.FUN = "MakeSignature";
GARevFun.FUN = "StSgn";
}
InToken.PIN = UserPIN;
InToken.TBS = B64ToBeSign;
InToken.keyidb64 = keyidb64;
InToken.nonce = nonce;
InToken.withSigningTime = withSigningTime;
InToken.withCardSN = withCardSN;
InToken.checkValidity = checkValidity;
GARevFun.Para = HashAlg.toUpperCase();
GARevFun.UrFUN = UrRevFUN;
switch (GARevFun.Para) {
case "SHA256":
InToken.HashAlgorithm = "SHA256";
break;
case "SHA1":
InToken.HashAlgorithm = "SHA1";
break;
default:
l_iRetCode = 3400;
l_vRMsg = rMsg(l_iRetCode, "");
break;
}
if (B64ToBeSign == null) {
l_iRetCode = 3402;
l_vRMsg = rMsg(l_iRetCode, "");
}
if (UserPIN == null) {
l_iRetCode = 3403;
l_vRMsg = rMsg(l_iRetCode, "");
}
if (HashAlg == null) {
l_iRetCode = 3404;
l_vRMsg = rMsg(l_iRetCode, "");
}
if (UrRevFUN == null) {
l_iRetCode = 3405;
l_vRMsg = rMsg(l_iRetCode, "");
alert("輸入參數錯誤或不足");
}
if (checkGoodDay() == false) {
l_iRetCode = 3401;
l_vRMsg = rMsg(l_iRetCode, "");
}
if (l_iRetCode == 0) {
if (SignType.localeCompare("Cryp") == 0) {
SendData(
"http://localhost:61161/umakeSig",
"http://localhost:61161/ChtPopupForm",
"IC卡讀取中",
Gbjct.PppFrmStyle,
StSgn,
UrRevFUN
);
} else {
SendData(
"http://localhost:61161/sign",
"http://localhost:61161/ChtPopupForm",
"IC卡讀取中",
Gbjct.PppFrmStyle,
StSgn,
UrRevFUN
);
}
} else {
l_vRetData =
'{"RCode":"' +
l_iRetCode +
'", "B64Signature":"' +
l_B64Signature +
'","RMsg":"' +
l_vRMsg +
'"}';
InToken.RetObj = JSON.parse(l_vRetData);
if (UrRevFUN && typeof UrRevFUN === "function") UrRevFUN();
}
}