網上交易-使用JAVA調用U盾進行客戶認證的total solutionjavascript
1、經過用戶名和密碼來進行認證的弊病html
咱們有一個網站,爲了保證用戶在線交易傳輸數據的安全性,咱們會啓用一個HTTPS/SSL:java
可是,對於一些網上銀行或者是網購來講,黑客特別喜歡攻擊這樣的網站,有一種攻擊手法叫MIMAT(中間者攻擊),僞造SSL證書,讓客戶端的HTTP流,流到他那邊去,而後再進一步用暴力破解,來破解你HTTP傳輸時的密碼。git
1、改進的交易流程算法
咱們假設密碼已經被MIM拿到了,拿到就拿到唄,你們知道工商銀行網上轉貼劃款時除了輸入用戶名和密碼外,還會在點」下一步」時,跳出一個頁面,讓你插上你的U盾,而後再送一下交易密碼的過程吧?數據庫
這個就是」電子簽名認證」windows
2、先來回顧一下什麼叫電子簽名:api
公鑰加密,私鑰解密tomcat
私鑰簽名,公鑰認證安全
舉例:
1. A用本身的私鑰,對abcdefg進行sign,sign()函數返回一個byte[],這就是電子簽名。
2. 把A的公鑰和簽名送到公行後臺
3. 工行先看A的密碼輸的對不對,作一個數據庫校驗
工行用A的公鑰對A的簽名作verify運算,也獲得一個byte[]
4. 工行把工發過來的簽名byte[]和用A的公鑰作verify()後的byte[],兩個byte[]進行booleanverified = sig.verify(dcByPriv);
5. 若是verified爲true,表明A必定是客戶A本人且是工行的客戶(固然,A若是被人殺了,而且A的私鑰被殺他的人得到了這個不能算工行的責任)
3、用JAVA實現簽名過程
因而,根據上述過程先作一個POC,用JAVA來作電子簽名認證,代碼以下:
import java.security.*;
public class SimpleSignature {
private static void digitalSign(String text)throws Exception{ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); kpg.initialize(1024); KeyPair keyPair = kpg.generateKeyPair(); byte[] data = text.getBytes("UTF8"); Signature sig = Signature.getInstance("MD5WithRSA"); sig.initSign(keyPair.getPrivate()); sig.update(data);
byte[] signatureBytes=sig.sign(); System.out.println("Signature:\n"+Base64.encode(signatureBytes));
sig.initVerify(keyPair.getPublic()); sig.update(data); boolean verified = false; try{ verified = sig.verify(signatureBytes); }catch(SignatureException se){ se.printStackTrace(); verified = false; } if(verified){ System.out.println("Signature verified."); }else{ System.out.println("Signature did not match."); } } public static void main(String[] args){ try{ String text="abc"; digitalSign(text); }catch(Exception e){ e.printStackTrace(); } } } |
4、運用證書解決公鑰,私鑰傳輸的問題
1. 生成自簽名CA根證書
openssl genrsa -des3 -out ca.key 1024
openssl rsa -in server.key -out ca.key
openssl req -new -x509 -keyout ca.key -out ca.crt
2. 生成Web服務器證書
openssl genrsa -des3 -out shnlap93.key 1024
openssl rsa -in shnlap93.key -out shnlap93.key
openssl req -new -key shnlap93.key -out shnlap93.csr
openssl ca -in shnlap93.csr -out shnlap93.crt -cert ca.crt -keyfileca.key
3. 生成客戶端證書
openssl genrsa -des3 -out client.key 1024
openssl rsa -in shnlap93.key -out client.key
openssl req -new -key client.key -out client.csr
openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key
4. 把shnlap93.crt裝在服務器上
客戶端的IE導入client.crt(此處必須把crt再轉成p12格式)導入:
openssl pkcs12 -export -inkey client.key -in client.crt -out client.p12
1. 你們看到第4步中的那個key了吧,這個key就是客戶端的私鑰
你們看到第4步中的那個crt文件了吧?那個文件裏存着客戶端的公鑰(不是那個.key文件啊)
2. 寫一個servlet,客戶端訪問這個servlet時,該servlet自動從客戶端的IE獲取client.p12,而後把裏面的公鑰抽出來(因爲是公鑰,公開的,因此這個不存在安全不安全的因素)
3. 服務器拿着該客戶的私鑰(此處咱們先用這種方法來作),下面會講更高級的U盾存客戶端私鑰的作法)
1、而後套用(用JAVA實現簽名過程)中的算法,就能夠實現使用證書來進行客戶端和服務器的認證啦
須要解決的問題:
1. Servlet如何讀客戶端的認證
不少網上的朋友都說
「我用X509Certificate[]certs = (X509Certificate[]) request .getAttribute("javax.servlet.request.X509Certificate");
獲得的證書是個null」
幾乎沒有答案,這邊給出解決方案
a. 客戶端訪問這個servlet,客戶端和放這個servlet的j2eeapp必須實現「雙向認證」
b. J2ee app端(假設咱們這邊用TOMCAT實現),在實現雙向認證後,其實還不夠,須要加一個參數,不少人可能沒注意到這個參數,下面給出方案:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
enableLookups="false"disableUploadTimeout="true"
useURIValidationHack="false"
scheme="https"secure="true"
keystoreFile="D:/tomcat/conf/shnlap93.jks"keystorePass="xxxxxxx"
truststoreFile="D:/tomcat/conf/truststore.jks"truststorePass="aaaaaa"
truststoreType="JKS"
clientAuth="true"sslProtocol="TLS" />
看到上面那個標紅的地方了吧?就是這個參數沒加,所以不少人就算啓用了雙向認證,你的servlet在拿ie端的證書時仍是會獲得null值
2. 好,如今客戶端的公鑰拿到了,怎麼拿私鑰?
前面說了,咱們先作一個簡單的,寫死的,就是把客戶端的私鑰放在咱們的網站的某個目錄下,而後用程序去讀出來。
所以咱們的過程以下:
a. 客戶端經過IE輸入他的交易密碼
b. 而後點「提交」按鈕,POST到咱們的這個servlet
c. Servlet先讀放在網站某個目錄下的該客戶的私鑰,loadPrivateKey後用私鑰對客戶提交的form裏的密碼進行簽名。
d. Servlet得到客戶端IE裏的證書,把公鑰拿出來,而後用公鑰對簽完名的byte[]進行verify,獲得true表明認籤成功,false認籤失敗,下面是咱們的servlet
此處須要注意的是咱們用openssl簽出的private key是不能直接被java所訪問的,由於它含用:
#begin certificate
…
#end certificate
這樣的東西,而JAVA只認#begin…#end當中的那塊東西,怎麼辦:
使用下面這條使用把openssl簽出的key轉成咱們java能夠認的rsa的KEY
opensslpkcs8 -topk8 -inform PEM -outform DER -in shnlap93.key -out pkcs8_der.key –nocrypt
下面是咱們的servlet的核心片斷,拿客戶端IE的公鑰,拿網站某個目錄擺放的私鑰,而後調用標準的JAVA電子簽名
private PublicKey getPubKeyFromIE(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("...security receive done..." + request.getScheme()); String issue, after, before, subject; String serialno, signalg; int version; String cipherSuite = ""; PublicKey pk = null; try { cipherSuite = (String) request .getAttribute("javax.servlet.request.cipher_suite"); System.out.println("cipherSuite=====" + cipherSuite); // response.setContentType("text/plain"); // FileInputStream fis = new FileInputStream("d://paramita.cer "); PrintWriter out = response.getWriter(); if (cipherSuite != null) { X509Certificate[] certs = (X509Certificate[]) request .getAttribute("javax.servlet.request.X509Certificate"); /* ibm http server us followings */ // X509Certificate[] certs = (X509Certificate[]) request // .getAttribute("javax.net.ssl.peer_certificates");
if (certs != null) { if (certs.length > 0) { X509Certificate t = certs[0]; pk = t.getPublicKey(); } } else { if ("https".equals(request.getScheme())) { out.println("This was an HTTPS request, " + "but no client certificate is available"); } else { out.println("This was not an HTTPS request, " + "so no client certificate is available"); } } } return pk; } catch (Exception e) { throw new ServletException(e); } } |
2、私鑰放在U內造成U盾
看到這邊,你們已經蛋疼了吧?
要不要喝口水?
只有平時多蛋疼,真的碰到問題時纔不會疼,這就叫「老亂」。
1. 去買個支持安裝RSA,加密,解密的證書的U盤吧,不貴,幾十塊錢,隨盤一塊兒贈送一套軟件,用這套軟件把(pkcs8_der.key)通過OPENSSL轉換事後的私鑰write進去吧(經過隨盤自帶的工具吧,這個不說了,由於每一個人買的U盤所帶的工具都不同。
2. 寫個applet,這個applet就一個輸入框,用於讓客戶輸入密碼使用
3. 而後使用javascript調用applet,讀客戶本地的U盤,把私鑰讀出來,而後該APPLET用讀出的私鑰和客戶輸入的密碼進行簽名,把簽完名後的byte[]轉成base64,加上客戶端輸入的密碼一塊兒post到咱們剛纔寫的那個servlet中去。
4. 客戶端安裝由網站頒放的證書(P12格式導入IE的「我的信任域中」)
5. 咱們的那個servlet從客戶端的IE獲得證書,導出公鑰,拿公鑰+簽名後的byte[]再作一個verify(),true表明認籤,false表明失敗(無論失敗緣由),反正這個客戶認籤失敗。
6. 以上這一步其實已經認證經過了,這時能夠把客戶輸入的用戶名和密碼進行一次基於數據庫或者是LDAP的authentication,這樣就能夠保證是這個客戶本人在進行交易了。
此處,須要解決的技術問題有兩此:
a. APPLET調用本地U盤
b. 如何使用java script調用U盤
下面給出詳細解決方案:
a. 你買U盤時必定要記得它是支持JAVA調用的啊,通常U盤廠商會提供一個DLL,如:abc.dll,而後JAVA經過JNI調用這個dll,看到這邊不要怕,廠商會提供完整的sample和api告訴你怎麼調用該DLL的,照着SAMPLE寫就行。
若是applet要調用客戶端的u盤,該dll能夠經過installshield等安裝分發工具製做成分發包給客戶自行安裝。
在製做DLL安裝分發包時,必定要把用於給javajni調用的dll經過安裝工具自動copy到客戶端的xp/windows的system32目錄下,通常installshield或者是installanywhere等工具都帶這個功能的。
這也是你們在第一次用工行的U盾時,IE會提示要裝一個什麼控件,而後再要下載一個控件讓你容許的道理,其實第一步就是把用來讀U盾的dllcopy到你的系統的system32目錄的一個過程,後一個過程就是讓你容許下載applet/activex的過程。
可是,這邊的問題是APPLET因爲JAVA的沙箱機制,不能調用數據庫,SOCKET及本地資源的,OK,不要擔憂。
咱們不是已經有了CA和證書了嗎?如今咱們用咱們的證書對這個APPLET籤個名,它就可以調用本地的一切資源了。
咱們如今用shnlap93.key,shnlap93.crt兩個服務器端用的證書,咱們有ca.crt,ca.key自簽名root根證書,下面咱們來造一個用於簽名applet的jks文件吧。
對於applet簽名必定要用JKS文件,爲何?
1) 由於jks是含有私鑰的
2) 套用萬能定律「私鑰簽名,公鑰認證」
所以要用jks 文件
下面咱們來生成這個jks吧:
keytool -genkey -alias shnlap93X509 -keyalg RSA -keysize 1024 -dname "CN=shnlap93.cts.com, OU=insurance, O=CTS, L=SH, S=SH, C=CN" -keypass aaaaaa -keystore shnlap93.jks -storepass aaaaaa
keytool -certreq -alias shnlap93X509 -sigalg "MD5withRSA" -file shnlap93.csr -keypass aaaaaa -keystore shnlap93.jks -storepass aaaaaa
openssl x509 -req -in shnlap93x509.csr -out shnlap93x509.pem -CA ca.crt -CAkey ca.key -CAserial ca-cert.srl -CAcreateserial -days 7200
keytool -import -alias rootca -trustcacerts -file ca.crt -keystore shnlap93.jks -storepass aaaaaa keytool -import -alias shnlap93X509trust -file shnlap93x509.pem -keystore shnlap93.jks -storepass aaaaaa |
注意:
1)在提示要求輸入CN值是(common name),這個值的IP必須和你的服務器(咱們指TOMCAT)所在的IP或者是機器名(強烈建議你們用機器名而不要用IP)必須一至的啊
如今咱們有了這個JKS,這個JKS是咱們在上面實現TOMCAT雙向SSL認證時所須要用的JKS,也是咱們簽名時須要用的JKS
2)keytool -import -alias shnlap93X509trust -file shnlap93x509.pem-keystore shnlap93.jks -storepass aaaaaa這一步中的alias中的別名的值絕對不可以和第一步:
keytool -genkey-alias shnlap93X509 -keyalg RSA -keysize 1024 -dname "CN=shnlap93.cts.com,OU=insurance, O=CTS, L=SH, S=SH, C=CN" -keypass aaaaaa -keystoreshnlap93.jks -storepass aaaaaa
中的值重名的啊。
3)這個jks生成完後使用:
Keytool –v –list –keystore shnlap93.jks後,你應該會看到「3」條entry,其中一條keyentry, 兩條trustcert。
下面給出applet的簽名過程:
jarsigner -verbose -verifyClientAuthenticationApplet.jar shnlap93X509(key entry的別名)
b. Javascript調用applet,下面直接看咱們的測試html頁的源碼吧:
<script language="javascript"> function getSignByPrivKey(){ var dcmsg=document.authClient.getSignature(); //alert(msg); if(dcmsg!="-1") { document.digitalsig.dc_code.value=dcmsg; document.digitalsig.submit(); }else{ alert("請插入正確的U盾"); } } </script>
<OBJECT id="authClient" classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" WIDTH = 100 HEIGHT = 25 ALIGN = middle VSPACE = 0 HSPACE = 0 codebase="http://java.sun.com/products/plugin/1.2/jinstall-12-win32.cab#Version=1,2,0,0"> <PARAM NAME = CODE VALUE = "alice/framework/applet/AuthClient.class" > <PARAM NAME = ARCHIVE VALUE = "ClientAuthenticationApplet.jar" > <PARAM NAME="type" VALUE="application/x-java-applet;version=1.2"> </OBJECT> |
上面這個object就是applet的寫法,囉哩囉嗦一堆東西,怎麼寫啊,很簡單,你們在製做這個html頁時先用標準的applet標籤寫法
<APPLET CODE="test/AuthClient.class" ARCHIVE="ClientAuthenticationApplet.jar" WIDTH=350 HEIGHT=200 HSPACE=0 VSPACE=0 ALIGN=middle> </APPLET> |
而後再去下一個HtmlConvert把這個html轉一下就成了上面這一堆東西了,下載地址爲:
這個是SUN(不,如今是ORACLE-SUN)免費提供的applet轉IE所認格式的語句的標準工具。
必定要轉啊,不轉的話下面javascript調用不認啊
轉完後,要加一個ID:
<OBJECT id="authClient"classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
如上紅色標粗的部分,不是classid啊,這個是htmlconvert自動給加的,必定要加這個id,不加這個id,javascript就不能經過documnt.authClient這樣的形式調用applet了。
所以到這邊你們知道了吧,其實javascript調用applet就是把applet當一個html中的組件事調用的,只要這個applet有publich聲明開頭的方法,javascript就能夠調用這種方法了,如:
vardcmsg=document.authClient.getSignature();
3、完整客戶端交易認證流程
1.客戶先安裝U盤驅動(客戶端運行vender作的dll安裝至windows的system32目錄的安裝程序)
2.客戶打開一個HTML(不用https訪問,直接用http訪問就好了)
3.客戶在網頁的表單中提入用戶名密碼點提交
4.此時彈出一個窗口,該窗口含有applet
5.該彈出HTML窗口中的經簽名的applet自動下載到客戶端
6.Applet經過loadSystemLibrary(dll名)調用相關U盤驅動讀出U盤內客戶本身的私鑰
7.Applet內部程序用私鑰對客戶剛纔輸入的密碼進行sign,把sign後的md5/sha(哈希值)還給表單,跟隨着表單內客戶輸入的密碼一塊兒提交給咱們的servlet
8.咱們的servlet從客戶的IE導出客戶安裝的服務端的證書,從證書導出公鑰
9.用公鑰對post過來的客戶的sign的那個hash值進行verify()操做,返回是true,表明認證成功,而後接下拿拿客戶輸入的密碼再通過基於DB或者是LDAP的authentication,若是verify()是false直接經過servletresponse給客戶一條錯誤代碼,如:
請正確插入U盤(你就插吧, Come on BAYBAY!)。
下面給出完整的html,servlet, applet代碼:
<html> <head> <script language="javascript"> function getSignByPrivKey(){ var dcmsg=document.authClient.getSignature(); //alert(msg); if(dcmsg!="-1") { document.digitalsig.dc_code.value=dcmsg; document.digitalsig.submit(); }else{ alert("請插入正確的U盾"); } } </script> </head> <body>
<form name="digitalsig" action="https://shnlap93.cts.com/alice/servlet/securityReceive" method="post"> <input type="hidden" name="dc_code"> <table border="0" align="center"> <tr> <td> 交易密碼(請查入U盾): </td> <td align="left"> <OBJECT id="authClient" classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" WIDTH = 100 HEIGHT = 25 ALIGN = middle VSPACE = 0 HSPACE = 0 codebase="http://java.sun.com/products/plugin/1.2/jinstall-12-win32.cab#Version=1,2,0,0"> <PARAM NAME = CODE VALUE = "alice/framework/applet/AuthClient.class" > <PARAM NAME = ARCHIVE VALUE = "ClientAuthenticationApplet.jar" > <PARAM NAME="type" VALUE="application/x-java-applet;version=1.2"> </OBJECT> </td> </tr> <tr> <td>交易密碼:</td> <td align="left"><input type="password" name="inputPwd"></td> </tr> <tr> <td align="right" colspan="2"> <input type="button" name="submit_btn" value="submit" onclick="getSignByPrivKey();"> </td> </tr> </table> </form> </body> |
SecurityReceiveServlet代碼
public class SecurityReceive extends HttpServlet { private static final long serialVersionUID = 1L;
/** * @see HttpServlet#HttpServlet() */ public SecurityReceive() { super(); // TODO Auto-generated constructor stub }
/** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ private byte[] sign(String password) throws Exception {
try { byte[] privKeyCode = SecurityHelper .loadOpenSSLKey("d:/ca/pkcs8_der.key");
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privKeyCode); RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory .generatePrivate(privateKeySpec); Signature dsa = Signature.getInstance("MD5WithRSA"); dsa.initSign(privateKey); dsa.update(password.getBytes()); byte[] sig = dsa.sign(); return sig; } catch (Exception e) { throw new Exception(e); } }
private PublicKey getPubKeyFromIE(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("...security receive done..." + request.getScheme()); String issue, after, before, subject; String serialno, signalg; int version; String cipherSuite = ""; PublicKey pk = null; try { cipherSuite = (String) request .getAttribute("javax.servlet.request.cipher_suite"); System.out.println("cipherSuite=====" + cipherSuite);
// response.setContentType("text/plain"); // FileInputStream fis = new FileInputStream("d://paramita.cer "); PrintWriter out = response.getWriter(); if (cipherSuite != null) { X509Certificate[] certs = (X509Certificate[]) request .getAttribute("javax.servlet.request.X509Certificate"); /* ibm http server us followings */ // X509Certificate[] certs = (X509Certificate[]) request // .getAttribute("javax.net.ssl.peer_certificates");
if (certs != null) { if (certs.length > 0) { X509Certificate t = certs[0]; pk = t.getPublicKey(); } } else { if ("https".equals(request.getScheme())) { out.println("This was an HTTPS request, " + "but no client certificate is available"); } else { out.println("This was not an HTTPS request, " + "so no client certificate is available"); } } } return pk; } catch (Exception e) { throw new ServletException(e); } }
private boolean verifySignature(byte[] dcByPriv, String password, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean verified = false; try { if (dcByPriv == null) { return false; } byte[] data = password.getBytes("UTF8"); Signature sig = Signature.getInstance("MD5WithRSA"); sig.initVerify(getPubKeyFromIE(request, response)); sig.update(data); try { verified = sig.verify(dcByPriv); } catch (SignatureException se) { se.printStackTrace(); verified = false; } return verified; } catch (Exception e) { throw new ServletException(e); } }
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean answer = false; String password = ""; String dcByPrivBase64 = ""; byte[] dcByPriv = null; password = (String) request.getParameter("inputPwd"); dcByPrivBase64 = (String) request.getParameter("dc_code"); try { dcByPriv = Base64.decode(dcByPrivBase64.getBytes()); } catch (Exception e) { e.printStackTrace(); dcByPriv = null; } answer = verifySignature(dcByPriv, password, request, response); System.out.println("answer=====" + answer); }
/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
} |
咱們的appletAuthClient的代碼
/* * To change this template, choose Tools | Templates * and open the template in the editor. */
/* * AuthClient.java * * Created on 2011-9-6, 13:08:02 */ package alice.framework.applet;
import RY3jni.*;
import java.lang.*; import java.security.KeyFactory; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.spec.EncodedKeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.io.*; import alice.util.Base64;
/** * */ public class AuthClient extends javax.swing.JApplet {
/** Initializes the applet AuthClient */ public void init() { /* Set the Nimbus look and feel */ // <editor-fold defaultstate="collapsed" // desc=" Look and feel setting code (optional) "> /* * If Nimbus (introduced in Java SE 6) is not available, stay with the * default look and feel. For details see * http://download.oracle.com/javase * /tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager .getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager. setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(AuthClient.class.getName()).log( java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(AuthClient.class.getName()).log( java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(AuthClient.class.getName()).log( java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(AuthClient.class.getName()).log( java.util.logging.Level.SEVERE, null, ex); } // </editor-fold>
/* Create and display the applet */ try { java.awt.EventQueue.invokeAndWait(new Runnable() {
public void run() { initComponents(); } }); } catch (Exception ex) { ex.printStackTrace(); } }
/** * This method is called from within the init() method to initialize the * form. WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() {
inputPassword = new javax.swing.JPasswordField();
getContentPane().setLayout( new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.LINE_AXIS));
inputPassword.setText("jPasswordField1"); getContentPane().add(inputPassword); }// </editor-fold>
private IRY3 getROCK3Handler() throws Exception { IRY3 ry = new CRY3(); RY3Def flag = new RY3Def(); // String chPid = ""; String chPin = ""; String chSeed = "123456"; // int[] Count = new int[4]; int[] RemainCount = new int[4]; int[] FreeSize = new int[1]; // char[] charPid = new char[16]; // 8 char[] charPin = new char[30]; // 24 char[] charSeed = new char[16]; // 6 char[] charHardID = new char[32]; // 16 // byte[] randbuf = new byte[16]; byte[] tmpbuf = new byte[2048]; String voucher = "aaaaaa"; charPid = new char[] { 'F', 'E', 'C', '2', 'B', 'F', 'E', '1' }; // chPin = "123456781234567812345678"; charPin = chPin.toCharArray(); try { ry.RY3_Find(charPid, Count); if (Count[0] != 0) { ry.RY3_Open(1); } else { return null; } return ry; } catch (Exception e) { throw new Exception(e); }
}
private RSAPrivateKey getPrivateKeyFromRC3() throws Exception { IRY3 ry = null; RSAPrivateKey privateKey = null; byte[] privKeyCode = new byte[1024]; try { ry = getROCK3Handler(); ry.RY3_Read(0, privKeyCode, 1024); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privKeyCode); privateKey = (RSAPrivateKey) keyFactory .generatePrivate(privateKeySpec); return privateKey; } catch (Exception e) { throw new Exception(e); } }
public String getUserInputPwd() { return new String(this.inputPassword.getPassword()); }
public String getSignature() { RSAPrivateKey privateKey = null; try { privateKey = getPrivateKeyFromRC3(); Signature dsa = Signature.getInstance("MD5WithRSA"); dsa.initSign(privateKey); String pwd = new String(this.inputPassword.getPassword()); dsa.update(pwd.getBytes()); byte[] sig = dsa.sign(); System.out.println("success"); return new String(Base64.encode(sig)); } catch (Exception e) { System.out.println("error: " + e); e.printStackTrace(); return "-1"; } }
// Variables declaration - do not modify private javax.swing.JPasswordField inputPassword; // End of variables declaration } |