`

JAVA调用U盾进行客户认证实例

 
阅读更多

本文转自:http://www.fengfly.com/plus/view-210090-1.html

 

一、通过用户名和密码来进行认证的弊病

       我们有一个网站,为了保证用户在线交易传输数据的安全性,我们会启用一个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.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转一下就成了上面这一堆东西了,下载地址为:

http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-client-419417.html#7251-plugin-1.2-win-JPR

这个是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

}

 

 

 

 

 

  • 大小: 118.7 KB
  • 大小: 103.4 KB
  • 大小: 163.1 KB
分享到:
评论

相关推荐

    java调用Gmssl国密接口实例

    java调用Gmssl中国密接口进行对称与非对称加解密等运算,动态so库进行接口jni方式调用,采取接口形式对外暴露,方便对接系统调用相关java接口进行相关运算操作。

    JAVA中使用LDAP进行用户认证

    JAVA中使用LDAP进行用户认证 JAVA中使用LDAP进行用户认证是指在JAVA应用程序中使用轻量级目录访问协议(LDAP)来进行用户身份验证。LDAP是一种基于X.500标准的目录访问协议,但它更简单、更灵活,可以根据需要进行...

    java调用com组件实例

    Java调用COM组件是Java与非Java环境交互的一种方式,主要应用于Windows平台,因为COM(Component Object Model)是微软提出的一种面向对象的技术,主要用于构建Windows应用程序和服务。在Java中调用COM组件,可以...

    Java调用SPSS的实例

    使用Java API,我们可以将XML中的语法解析并执行,然后获取分析结果。 总的来说,Java调用SPSS是一项实用的技术,它允许开发者利用Java的强大功能和SPSS的统计分析能力,实现数据处理和分析的自动化。不过,由于...

    java调用百度翻译接口简单实例

    4. **JSON解析**:如果不用第三方库,可以使用Java内置的`javax.json`包进行解析。先将JSON字符串转换为`JsonReader`,然后逐层解析并提取需要的信息,如翻译结果。 5. **异常处理**:在整个过程中,应处理可能出现...

    java调用动态链接库实例 java调用动态链接库实例 java调用动态链接库实例

    Java本身并不直接支持调用原生代码,但它通过Java Native Interface (JNI) 提供了一个桥梁,使得Java可以与操作系统级别的功能进行交互。下面我们将详细讨论如何在Java中调用动态链接库,并以Linux环境下的SO库为例...

    java调用.asmx详细实例

    JAVA调用.asmx详细实例,应用于java web 工程中。很细致哟

    java调用soap接口案例

    通过以上知识点的学习和实践,你可以掌握如何使用Java调用SOAP接口,以及如何根据具体需求进行定制。在处理天气信息这样的案例中,理解SOAP协议和相关API的使用,将使你能够轻松地与各种Web服务进行交互。

    Java调用SPSS的实例.docx

    在Java编程环境中调用SPSS(Statistical Product and Service Solutions)是通过SPSSINC API for Java实现的。这个API允许开发者在Java应用中无缝集成SPSS的功能,执行统计分析、数据处理等任务。SPSSINC API for ...

    JAVA实现ElasticSearch的简单实例

    Java实现Elasticsearch的简单实例主要涉及以下几个关键知识点: 1. **Elasticsearch基础**:Elasticsearch(ES)是一个开源的、分布式全文搜索引擎,它提供了实时数据分析的能力,广泛用于日志分析、监控、搜索应用...

    swig实例java调用c

    本实例主要讲解如何使用Swig来实现Java调用C代码,并通过DLL动态链接库进行交互。 首先,Swig是一个接口生成器,它读取源代码中的特定注释,然后生成必要的绑定代码,使得Java、Python、Perl等语言可以调用C或C++的...

    工行捷德U盾 Win7 32/64位 官方驱动

    【工行捷德U盾 Win7 32/64位 官方驱动】是一款专为工商银行用户设计的安全认证工具,适用于Windows操作系统,包括32位和64位版本。这款驱动程序的主要功能是确保用户的捷德U盾在Win7系统上能够正常工作,提供安全的...

    Java RPC调用示例

    Java RPC(Remote Procedure Call)调用是分布式系统中常见的通信方式,它允许一个程序在不关心远程系统具体实现的情况下调用另一个网络上的程序。在这个Java RPC调用示例中,我们将探讨RPC的基本概念、实现机制以及...

    java调用json参数的webservice

    为了使得Java客户端能够调用WebService服务,需要使用一些工具,例如JAX-WS(Java API for XML Web Services),它是Java SE的一部分,用于创建WebService客户端和服务端。 综上所述,通过Java调用带有JSON参数的...

    Java 调用wsdl例子

    Java 调用 WSDL 例子是指使用 Java 语言来调用远程的 Web 服务,该 Web 服务是通过 WSDL 文件发布的。在 WSDL 文件中,包含了该 Web 服务暴露在外面的接口信息。 WSDL 文件是 Web 服务描述语言的缩写,用于描述 Web...

    java调用webService实例

    本实例将通过一个简单的"HelloWorld"示例,讲解如何使用Java来调用Web Service。 首先,我们需要了解Web Service的基本概念。Web Service是一种基于网络的、独立于平台的服务,它能够通过标准的XML(可扩展标记语言...

    Java实现Shazam声音识别算法的实例代码

    6. Java实现Shazam声音识别算法:在Java中,可以使用Java Sound API和FFT算法来实现Shazam声音识别算法。通过AudioSystem获取音频,傅里叶变换将时域信号转换为频域信号,获取音频指纹,最后匹配指纹契合度来识别...

    C++和Java互相调用实例

    本文将深入探讨如何在C++和Java之间进行互相调用的实例,主要关注Android环境下的JNI(Java Native Interface)技术,同时涉及NDK(Native Development Kit)开发。 标题:“C++和Java互相调用实例”意味着我们将...

    java调用扫描仪

    当我们需要在Java应用中实现与硬件设备交互的功能,如调用扫描仪进行文档扫描,就需要借助特定的库和接口。本篇文章将深入探讨如何在Java环境中调用扫描仪,并提供相关实践示例。 首先,理解Java与硬件设备交互的...

    Java项目开发实例代码

    "Java项目开发实例代码"这个资源提供了与"Java项目开发实例自学手册"相配套的实际编程示例,旨在帮助初学者和进阶者深入理解Java语言在实际项目中的应用。 Java是一种广泛使用的面向对象的编程语言,以其平台独立性...

Global site tag (gtag.js) - Google Analytics