
var nDevID = 1;
var handle1 = 0;
var portNo ="";

//var MainKey = "";
//var AppKey = "";
var AuthKey = "57415443484441544154696D65434F53";
//var MainKey="894154gui8444154zhou696D6softF53";
var MainKey="57415443484441544154696D65434F53";
var AppKey="894154gui8444154zhou696D6softfdc";
function chr2Unicode(str) {
	if ('' != str) {
		var st, t, i;
		st = '';
		for (i = 1; i <= str.length; i ++){
			t = str.charCodeAt(i - 1).toString(16);
			if (t.length < 4)
			while(t.length <4)
				t = '0'.concat(t);
			t = t.slice(2, 4).concat(t.slice(0, 2))
			st = st.concat(t);
		}
		return(st.toUpperCase());
	}
	else {
			return('');
	}
}

function unicode2Chr(str) {
	if ('' != str) {
		var st, t, i
		st = '';
		for (i = 1; i <= str.length/4; i ++){
			t = str.slice(4*i-4, 4*i-2);
			t = str.slice(4*i-2, 4*i).concat(t);
			st = st.concat('%u').concat(t);
		}
		st = unescape(st);
		return(st);
	}
	else
		return('');
}

/*1.1 打开端口******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function OpenICReader()
{
	if ( handle1 > 0 )
	{
		CloseICReader();
	}

	portNo = "usb1" ;
	handle1 = WdcrwvOCX.OpenCtrl( portNo );
	if ( handle1 < 0 )
	{
		window.status = "端口" + portNo + "打开失败!";
	}
	else
	{
		window.status = "端口" + portNo + "已打开";
		var resp = WdcrwvOCX.ICCReset (handle1);
	}
	return;
}

/*1.2 关闭端口******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function CloseICReader()
{
	var sw = WdcrwvOCX.CloseCtrl( handle1 );
	if (sw == 0)
	{
		window.status = "端口" + portNo + "已关闭";
	}
	return;
}

/*1.3 卡复位******************************************************************************
输入：	无
返回：	字符型 respdata 返回复位应答ATR （包括卡状态，返回长度和执行状态）
******************************************************************************************/
function ResetCard()
{
	if( handle1 <= 0 )
	{
		result = "没有打开端口。";
		throw result;
	}
	
	var result = "";
	var resp = WdcrwvOCX.ICCReset (handle1);
	var len = resp.length;
	var cardin = resp.substr( 0, 1 );
	var respdata = resp.substr( 5,len - 9);
	var sw = resp.substr( len - 4, 4 );
	
	if ( cardin != "0")
	{
		result = "没有检测到卡片";
		throw result;
	}
	else if( sw != "9000")
	{
		reslult = sw;
		throw result;
	}
	return respdata;
}

function Reset()
{
	var receiveError;
	try
	{
		var resp = ResetCard();
	}
	catch(receiveError)
    	{
 	       alert( receiveError );
	}
	return;
}
/*1.4 向卡发送命令******************************************************************************
输入：	数值型 handle	打开读卡设备端口句柄
		字符型 cardcmd	APDU命令代码
		字符型 prem		执行报错（内容，位置）说明
返回：	字符型 resp		卡执行返回结果RESPONCE
******************************************************************************************/
function sendcmd( handle, cardcmd, prem )
{
	var result = "";
	var resp = WdcrwvOCX.SendCommand (handle,cardcmd.length,cardcmd);
	var len = resp.length;
	var cardin = resp.substr( 0, 1 );
	var respdata = resp.substr( 5,len - 9);
	var sw = resp.substr( len - 4, 4 );
	
	if ( cardin != "0")
	{
		result = "没有检测到卡片！  " +  prem;
		throw result;
	}
	else 
	if( sw != "9000")
	{
		result = sw + "  " + prem + " " + cardcmd;
		throw result;
	}

	return respdata;
}

/*2.1 创建keyPro结构，两组密钥******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function IssueCard()
{
 	var rem,rand,cmd,sw,resp;
 	var receiveError = "";
 	
// 	if(MainKey == "")
// 	{
// 		MainKey = RSATestForm.CurrentMainKey.value;
// 	}
 	
// 	alert(MainKey);

	window.status = "";
	try
	{
		window.status = "创建卡结构中，请稍候…………";
		OpenICReader();
		resp = Reset();
		
		//External Authentication
		rem = "外部认证主控密钥";
		cmd = "0084000008";
		rand = sendcmd( handle1, cmd, rem );
		
		//选择应用3F01  
//		rem = "选择文件 3F01";  cmd = "00A40000023F01";  
//		resp = sendcmd( handle1, cmd, rem );  
//		var len = resp.length;  sw = resp.substr( len - 4, 4 );  
//		if( sw != "9000")  
//		{   
		    //选择二进制文件0001   
//		    rem = "选择二进制文件0001";   
//		    cmd = "00A40000020001";   
//		    resp = sendcmd( handle1, cmd, rem );    
//		    sw = resp.substr( len - 4, 4 );   
//		    if( sw != "9000")   
//		    {   
//		        result 0;    
//		        throw result;  
//		      } 
//		}
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + rand;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002010010" + MainKey.substr( 16, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "0082000008" + resp;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		//清除卡片结构
		rem = "清除卡片结构 ";
		cmd = "800E000000";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//主文件MF下创建KEY文件
		rem = "创建MF key文件";
		cmd = "80E00000073F005000F0FFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//安装卡片主控密钥
		rem = "安装MF 主控密钥";
		cmd = "80D401001539F0F0AAFF" + MainKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//创建应用3F01
		rem = "创建DF文件 3F01";
		cmd = "80E03F0108380100F0F0FFFFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		//选择应用3F01
		rem = "选择文件 3F01";
		cmd = "00A40000023F01";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//3F01下创建KEY文件
		rem = "创建3F01 key文件";
		cmd = "80E00000073F005000F0FFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//安装3F01应用主控密钥
		rem = "安装3F01应用主控密钥";
		cmd = "80D401001539F0F0AAFF" + AppKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//安装3F01应用维护密钥WATCHDATATimeCOS
		rem = "安装3F01应用维护密钥WATCHDATATimeCOS";
		cmd = "80D401001536F0F0FFFF" + MainKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//创建二进制文件0001
		rem = "创建二进制文件0001";
		cmd = "80E0000107280050F0F0FFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		window.status = "创建卡结构完成。";
//		alert("Create card file finish!");
        return 1;
	}
	catch(receiveError)
    {
        alert( receiveError );
	}
	return;
}

/*2.1 写二进制文件******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function WriteBinaryFile(str)
{
 	var rem,rand,cmd,sw,resp;
 	var receiveError = "";
 	var InputData = "";
  	var datalen = 0;
 	var lenhex;
 	var uniText;
 	

	window.status = "";
	
	try
	{
		window.status = "写二进制文件中，请稍候…………";
		
		InputData = str;//RSATestForm.text_input.value;
//		alert(InputData);
		
		if ( InputData.length == 0 )
		{
			rem = "请输入数据！";
			throw rem;
		}		
		
		uniText = chr2Unicode(InputData);
		InputData = uniText;
//		alert(InputData);
		
		OpenICReader();
		resp = Reset();
	 			//选择应用3F01  
		rem = "选择文件 3F01";  
        cmd = "00A40000023F01";  
		resp = sendcmd( handle1, cmd, rem );  
		var len = resp.length;  
		sw = resp.substr( len - 4, 4 );  
		if( sw != "9000")  
		{   
		    //选择二进制文件0001   
		    rem = "选择二进制文件0001";   
		    cmd = "00A40000020001";   
		    resp = sendcmd( handle1, cmd, rem );    
		    sw = resp.substr( len - 4, 4 );   
		    if( sw != "9000")   
		    {   
		       if (!confirm("该卡已经发过了,需要重新发放吗!"))
		           return;    
		    } 
		}
		resp = Reset();
//	 	if(MainKey == "")
//	 	{
//	 		MainKey = RSATestForm.CurrentMainKey.value;
//	 	}
	 	
//	 	alert(MainKey);
		
		//External Authentication
		rem = "外部认证主控密钥";
		cmd = "0084000008";
		rand = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + rand;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002010010" + MainKey.substr( 16, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "0082000008" + resp;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		//清除卡片结构
		rem = "清除卡片结构 ";
		cmd = "800E000000";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//主文件MF下创建KEY文件
		rem = "创建MF key文件";
		cmd = "80E00000073F005000F0FFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//安装卡片主控密钥
		rem = "安装MF 主控密钥";
		cmd = "80D401001539F0F0AAFF" + MainKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//创建应用3F01
		rem = "创建DF文件 3F01";
		cmd = "80E03F0108380100F0F0FFFFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		//选择应用3F01
		rem = "选择文件 3F01";
		cmd = "00A40000023F01";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//3F01下创建KEY文件
		rem = "创建3F01 key文件";
		cmd = "80E00000073F005000F0FFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//安装3F01应用主控密钥
		rem = "安装3F01应用主控密钥";
		cmd = "80D401001539F0F0AAFF" + AppKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//安装3F01应用维护密钥WATCHDATATimeCOS
		rem = "安装3F01应用维护密钥WATCHDATATimeCOS";
		cmd = "80D401001536F0F0FFFF" + MainKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//创建二进制文件0001
		rem = "创建二进制文件0001";
		cmd = "80E0000107280050F0F0FFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//选择二进制文件0001
		rem = "选择二进制文件0001";
		cmd = "00A40000020001";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//写二进制文件
		rem = "写二进制文件";
		datalen = InputData.length / 2;
		lenhex = datalen.toString(16);
		if ( lenhex.length < 2 )
		{
			lenhex = "0" + lenhex;
		}
				
		cmd = "00D60000" + lenhex + InputData;
//		alert(cmd);
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");		
		
		window.status = "写二进制文件完成。";

	}
	catch(receiveError)
    {
        alert( receiveError );
	}
	return;
}

/*2.1 读二进制文件******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function  ReadBinaryFile()
{
 	var rem,rand,cmd,sw,resp;
 	var receiveError = "";
 	var datalen = 0;
 	var lenhex;
 	var charText;
 	var i;
 	
	window.status = "";
	
	try
	{
		window.status = "读二进制文件中，请稍候…………";
		OpenICReader();
		resp = Reset();
		
		//选择应用3F01
		rem = "选择文件 3F01";
		cmd = "00A40000023F01";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//选择二进制文件0001
		rem = "选择二进制文件0001";
		cmd = "00A40000020001";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//读二进制文件
		rem = "读二进制文件";
		cmd = "00B0000050";
		resp = sendcmd( handle1, cmd, rem );
		
		lenhex = resp.length;
		for( i = 0; resp.substr(4 * i, 4) != "FFFF"; i ++)
		{
//			alert(resp.substr(4 * i, 4));
		}
		
		charText = resp.substr(0, (4 * i));
//		alert(charText);
		resp = unicode2Chr(charText);
		return resp;
//		RSATestForm.text_output.value = resp;
//		alert(rem + " OK");		
		
		window.status = "读二进制文件完成。";
		
		alert("成功读取卡号，请登录！");
	}
	catch(receiveError)
    {
        alert( receiveError );
	}
	return;
}

/*2.1 恢复卡片出厂结构******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function ResumeCard()
{
 	var rem,rand,cmd,sw,resp;
 	var receiveError = "";
	
// 	if(MainKey == "")
//	{
// 		MainKey = RSATestForm.CurrentMainKey.value;
// 	}
 	
// 	alert(MainKey);

	
	window.status = "";
	try
	{
		window.status = "恢复卡片出厂结构中，请稍候…………";
		OpenICReader();
		resp = Reset();
		
		//External Authentication
		rem = "外部认证主控密钥";
		cmd = "0084000008";
		rand = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + rand;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002010010" + MainKey.substr( 16, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "0082000008" + resp;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		//清除卡片结构
		rem = "clear card ";
		cmd = "800E000000";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//主文件MF下创建KEY文件
		rem = "创建MF key文件";
		cmd = "80E00000073F005000F0FFFF";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//安装卡片主控密钥
		rem = "安装MF 主控密钥";
		MainKey = "57415443484441544154696D65434F53";
		cmd = "80D401001539F0F0AAFF" + MainKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		window.status = "恢复卡片出厂结构完成。";
	}
	catch(receiveError)
    {
        alert( receiveError );
	}
	return;
}
/*3.1 测试APDU发送命令 执行结果返回到页面上  ******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function testcommand()
{
	var	receiveError;
	
	try
	{
		var resp =  sendcmd(handle1,cardcmd,"");
	}
	catch(receiveError)
    {
        alert( receiveError );
	}
	return;
}

/*修改卡片主控密钥  ******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function ChangeMainKey()
{
 	var rem,rand,cmd,sw,resp;
 	var receiveError = "";
	
// 	if(MainKey == "")
// 	{
// 		MainKey = RSATestForm.CurrentMainKey.value;
// 	}
 	
// 	alert(MainKey);
	
	window.status = "";
	try
	{
		window.status = "修改卡片主控密钥中，请稍候…………";
		OpenICReader();
		resp = Reset();
		
		//External Authentication
		rem = "外部认证主控密钥";
		cmd = "0084000008";
		rand = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + rand;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002010010" + MainKey.substr( 16, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "0082000008" + resp;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		//修改卡片主控密钥
		rem = "修改卡片主控密钥";
//		MainKey = RSATestForm.NewMainKey.value;
		cmd = "80D4390010" + MainKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		window.status = "修改卡片主控密钥完成。";
	}
	catch(receiveError)
    {
        alert( receiveError );
	}
	return;
}

/*修改应用主控密钥  ******************************************************************************
输入：	无
返回：	无
******************************************************************************************/
function ChangeAppKey()
{
 	var rem,rand,cmd,sw,resp;
 	var receiveError = "";
	
 	var newMainKey = MainKey;
 	
//	if(MainKey == "")
// 	{
//		MainKey = RSATestForm.CurrentMainKey.value;
// 	}
 	
// 	alert(MainKey);
 	
	window.status = "";
	try
	{
		window.status = "修改应用主控密钥中，请稍候…………";
		OpenICReader();
		resp = Reset();
		
		//External Authentication
		rem = "外部认证主控密钥";
		cmd = "0084000008";
		rand = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + rand;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002010010" + MainKey.substr( 16, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "1002000010" + MainKey.substr( 0, 16 ) + resp;
		resp = sendcmd( handle1, cmd, rem );
		
		cmd = "0082000008" + resp;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		//选择应用3F01
		rem = "选择文件 3F01";
		cmd = "00A40000023F01";
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");

		//修改应用主控密钥
		rem = "修改应用主控密钥";
//		AppKey = RSATestForm.NewAppKey.value;
		cmd = "80D4390010" + AppKey;
		resp = sendcmd( handle1, cmd, rem );
//		alert(rem + " OK");
		
		window.status = "修改应用主控密钥完成。";
	}
	catch(receiveError)
    {
        alert( receiveError );
	}
	return;

}

