使用JAVA數字證書做數字簽名認證

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章