版权声明:本文为博主原创文章,未经博主允许不得转载。
RSA-SHA1 signature
package com.enterise.test; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.ShortBufferException; import com.sun.org.apache.xml.internal.security.utils.Base64; /** * the RSA-SHA1 signature class with PKCS#1 v1.5 padding. */ public class Sign { public static void dump(String label, byte[] data) { String hex_str = Base64.encode(data); System.out.println(label+"="+hex_str); } /** * the example. * @param args * @throws UnsupportedEncodingException * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeySpecException * @throws ShortBufferException * @throws IllegalBlockSizeException * @throws BadPaddingException * @throws InvalidKeyException * @throws SignatureException */ public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, SignatureException { System.out.println("=======================RSA-SHA1 Sign====================="); String N = "90755611487566208138950675092879865387596685014726501531250157258482495478524769456222913843665634824684037468817980814231054856125127115894189385717148934026931120932481402379431731629550862846041784305274651476086892165805223719552575599962253392248079811268061946102234935422772131475340988882825043233323"; String e ="65537"; String d = "17790520481266507102264359414044396762660094486842415203197747383916331528947124726552875080482359744765793816651732601742929364124685415229452844016482477236658413327331659722342187036963943428678684677279032263501011143882814728160215380051287503219732737197808611144507720521201393129692996926599975297921"; String msg = "bsmith am a good guy."; byte[] indata = msg.getBytes("UTF-8"); Sign ser = new Sign(); ser.initPrivateKey(N, e, d); byte[] outdata = ser.sign(indata, 0, indata.length); dump("outdata", outdata); // byte[] outdata1 = new byte[ser.getCipherLen()]; // ser.sign(indata, 0, indata.length, outdata1, 0); // dump("outdata1", outdata1); // // Sign ver = new Sign(); // ver.initPublicKey(N, e); // System.out.println(String.format("result <?> true : %s", ver.verify(indata, outdata))); // System.out.println(String.format("result <?> true : %s", ver.verify(indata, outdata1))); // // byte[] indata1 = "bsmith is not a good guy.".getBytes("UTF-8"); // System.out.println(String.format("result <?> false : %s", ver.verify(indata1, outdata))); } private Signature ser; // signer. private PrivateKey sk; // private key for signer. private Signature ver; // verifier private PublicKey pk; // public key for verifier. private int KEY_BYTE_LEN; // the RSA key bytes length. public Sign() { } /** * init public key for verifier. * @param N N factor in RSA, aslo called modulus. * @param e e factor in RSA, aslo called publicExponent. * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeySpecException */ public void initPublicKey(String N, String e) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); BigInteger big_N = new BigInteger(N); KEY_BYTE_LEN = (big_N.bitLength())>>3; BigInteger big_e = new BigInteger(e); KeySpec keySpec = new RSAPublicKeySpec(big_N, big_e); pk = keyFactory.generatePublic(keySpec); } /** * init private key for signer. * @param N N factor in RSA, aslo called modulus. * @param e e factor in RSA, aslo called publicExponent, ignored, just keep compatible with C++ interface. * @param d d factor in RSA, aslo called privateExponent. * @throws NoSuchAlgorithmException * @throws NoSuchPaddingException * @throws InvalidKeySpecException */ public void initPrivateKey(String N, String e, String d) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); BigInteger big_N = new BigInteger(N); KEY_BYTE_LEN = (big_N.bitLength())>>3; BigInteger big_d = new BigInteger(d); KeySpec keySpec = new RSAPrivateKeySpec(big_N, big_d); sk = keyFactory.generatePrivate(keySpec); } /** * get the signer length in bytes. * this value is fixed, and is equals the RSA key bytes length. * @return the signer length. */ public int getCipherLen() { return KEY_BYTE_LEN; } /** * sign the input data to output data. * @param indata the input data. * @param inoff the input data offset. * @param inlen the input data length. * @param outdata the output data. * @param outoff the output data offset. * @return the actual output data length. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public int sign(byte[] indata, int inoff, int inlen, byte[] outdata, int outoff) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { initSigner(); ser.update(indata, inoff, inlen); return ser.sign(outdata, outoff, KEY_BYTE_LEN); } /** * sign the input data to output data. * @param indata the input data. * @param inoff the input data offset. * @param inlen the input data length. * @return the output data. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public byte[] sign(byte[] indata, int inoff, int inlen) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { initSigner(); ser.update(indata, inoff, inlen); return ser.sign(); } /** * sign the input data to output data. * @param indata the input data. * @return the output data. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public byte[] sign(byte[] indata) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { initSigner(); ser.update(indata); return ser.sign(); } /** * verify the input data and the signer. * @param plaindata the input plain data. * @param plainoff the input plain data offset. * @param plainlen the input plain data length. * @param signdata the signer data. * @param signoff the signer data offset. * @param signlen the signer data length. * @return the verify result, true passed, false failed. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public boolean verify(byte[] plaindata, int plainoff, int plainlen, byte[] signdata, int signoff, int signlen) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { initVerifier(); ver.update(plaindata, plainoff, plainlen); return ver.verify(signdata, signoff, signlen); } /** * verify the input data and the signer. * @param plaindata the input plain data. * @param signdata the signer data. * @return the verify result, true passed, false failed. * @throws NoSuchAlgorithmException * @throws InvalidKeyException * @throws SignatureException */ public boolean verify(byte[] plaindata, byte[] signdata) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { initVerifier(); ver.update(plaindata); return ver.verify(signdata); } private void initSigner() throws NoSuchAlgorithmException, InvalidKeyException { if (null == ser) { ser = Signature.getInstance("SHA1withRSA"); ser.initSign(sk); } } private void initVerifier() throws NoSuchAlgorithmException, InvalidKeyException { if (null == ver) { ver = Signature.getInstance("SHA1withRSA"); ver.initVerify(pk); } } }