论坛首页 Java企业应用论坛

使用JAVA数字证书做数字签名认证

浏览 5789 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-11-25   最后修改:2010-11-25
1.
keytool -genkey -keystore chinajavaworld.keystore -alias chinajavaworld

这个命令用来产生一个密匙库,执行完毕后会在当前操作目录中产生一个chinajavaworld.keystore的文件,在执行命令的时候还有提示你输入密匙库的密码,要记住,后面还要用到。

2.
keytool -export -keystore chinajavaworld.keystore -alias chinajavaworld -file chinajavaworld.cer

这个命令用来产生签名时所要用的证书。

3.在JAVA里操作,将Cer内容改为BASE64编码
//从密钥库中读取CA证书
String storepass = "123456";//前面设置的密码
FileInputStream in = new FileInputStream("e:\\license\\a\\chinajavaworld.keystore");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(in, storepass.toCharArray());
//获取证书
java.security.cert.Certificate c1 = ks.getCertificate("chinajavaworld");
//BASE64编码
System.out.println(StringUtils.encodeBase64(c1.getEncoded()));//将chinajavaworld.cer内容改为这里输出的内容


4.开始产生(测试)签名
     
 Signature signature;
        try
        {
            InputStream streamCert = new java.io.FileInputStream(
                        "e:\\license\\a\\test.cer");
            CertificateFactory factory = CertificateFactory.getInstance("X.509");
            Certificate cert = factory.generateCertificate(streamCert);
            System.out.println(StringUtils.encodeBase64(cert.getEncoded()));
            signature = Signature.getInstance("SHA1withDSA");
            signature.initVerify(cert.getPublicKey());
 
           	//要签名的指纹内容
            String sss = "Welcome to www.chinajavaworld.com,The java world for you forever.";
            //获取CA证书私钥
            PrivateKey priKey=(PrivateKey)ks.getKey("test",storepass.toCharArray());
            System.out.println("priKey:"+StringUtils.encodeHex(priKey.getEncoded()));
            
            //用私钥签名
            sig = Signature.getInstance("SHA1withDSA");
            sig.initSign(priKey);
            ByteArrayOutputStream streamRaw0 = new ByteArrayOutputStream();
            DataOutputStream streamSig0 = new DataOutputStream(streamRaw0);
            streamSig0.writeUTF(sss);
            sig.update(streamRaw0.toByteArray());
            String signatureS = StringUtils.encodeHex(sig.sign());
            System.out.println("signature:  "+signatureS);
 
            //用公钥做验证测试
            System.out.println("pubKey:"+StringUtils.encodeHex(cert.getPublicKey().getEncoded()));
            ByteArrayOutputStream streamRaw = new ByteArrayOutputStream();
            DataOutputStream streamSig = new DataOutputStream(streamRaw);
            streamSig.writeUTF(sss);
            signature.update(streamRaw.toByteArray());
            System.out.println("verify:   "+signature.verify(StringUtils.decodeHex(signatureS)));
        }
        catch(Exception e)
        {
            System.out.println(e);
        }


接下来,你就可以把chinajavaworld.cer和签名放在你的产品目录里了。认证的时候读取cer证书中的公钥,对签名内容进行认证就可以了。


  
public static String encodeBase64(byte data[])
    {
        boolean lineSep = false;
        int sLen = data == null ? 0 : data.length;
        if(sLen == 0)
            return new String("");
        int eLen = (sLen / 3) * 3;
        int cCnt = (sLen - 1) / 3 + 1 << 2;
        int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0);
        char dArr[] = new char[dLen];
        int s = 0;
        int d = 0;
        int cc = 0;
        do
        {
            if(s >= eLen)
                break;
            int i = (data[s++] & 0xff) << 16 | (data[s++] & 0xff) << 8 | data[s++] & 0xff;
            dArr[d++] = CA[i >>> 18 & 0x3f];
            dArr[d++] = CA[i >>> 12 & 0x3f];
            dArr[d++] = CA[i >>> 6 & 0x3f];
            dArr[d++] = CA[i & 0x3f];
            if(lineSep && ++cc == 19 && d < dLen - 2)
            {
                dArr[d++] = '\r';
                dArr[d++] = '\n';
                cc = 0;
            }
        } while(true);
        int left = sLen - eLen;
        if(left > 0)
        {
            int i = (data[eLen] & 0xff) << 10 | (left != 2 ? 0 : (data[sLen - 1] & 0xff) << 2);
            dArr[dLen - 4] = CA[i >> 12];
            dArr[dLen - 3] = CA[i >>> 6 & 0x3f];
            dArr[dLen - 2] = left != 2 ? '=' : CA[i & 0x3f];
            dArr[dLen - 1] = '=';
        }
        return new String(dArr);
    }
    
    
    public static final String encodeHex(byte bytes[])
    {
        StringBuffer buf = new StringBuffer(bytes.length * 2);
        for(int i = 0; i < bytes.length; i++)
        {
            if((bytes[i] & 0xff) < 16)
                buf.append("0");
            buf.append(Long.toString(bytes[i] & 0xff, 16));
        }
 
        return buf.toString();
    }
    
    
    public static final byte[] decodeHex(String hex)
    {
        char chars[] = hex.toCharArray();
        byte bytes[] = new byte[chars.length / 2];
        int byteCount = 0;
        for(int i = 0; i < chars.length; i += 2)
        {
            int newByte = 0;
            newByte |= hexCharToByte(chars[i]);
            newByte <<= 4;
            newByte |= hexCharToByte(chars[i + 1]);
            bytes[byteCount] = (byte)newByte;
            byteCount++;
        }
 
        return bytes;
    }

   发表时间:2010-11-26  
你最近发的帖子真多,这两天我都看过你三篇帖子了啊。
    是不是转载过来的,如果转载过来的请注明哦;
0 请登录后投票
   发表时间:2010-11-27  
弄个demo上来看看
0 请登录后投票
   发表时间:2010-11-27  
我是来看原作者出面指责楼主的。
0 请登录后投票
   发表时间:2010-11-27  
楼主最近很活跃喔。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics