一、通過用戶名和密碼來進行認證的弊病
我們有一個網站,為了保證用戶在線交易傳輸數據的安全性,我們會啟用一個HTTPS/SSL:
但是,對于一些網上銀行或者是網購來說,黑客特別喜歡攻擊這樣的網站, 有一種攻擊手法叫MIMAT(中間者攻擊), 偽造SSL證書,讓客戶端的HTTP流,流到他那邊去, 然后再進一步用暴力破解,來破解你HTTP傳輸時的密碼。

一、改進的交易流程
我們假設密碼已經被MIM拿到了,拿到就拿到唄,大家知道工商銀行網上轉貼劃款時除了輸入用戶名和密碼外,還會在點”下一步”時,跳出一個頁面,讓你插上你的U盾,然后再送一下交易密碼的過程吧?
這個就是”電子簽名認證”
二、先來回顧一下什么叫電子簽名:
公鑰加密,私鑰解密
私鑰簽名,公鑰認證
舉例:
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的私鑰被殺他的人獲得了這個不能算工行的責任)
三、用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(); } } } |
四、運用證書解決公鑰,私鑰傳輸的問題
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盾存客戶端私鑰的做法)
一、然后套用(用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); } } |
二、私鑰放在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.jarshnlap93X509(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();
三、完整客戶端交易認證流程
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 */ @Override 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 }
|
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
