日期:2014-05-20  浏览次数:20775 次

rsa算法
RSA(MD5(签名数据),私钥)

  请问rsa签名怎么弄,以及怎么生成公钥,私钥

 

------解决方案--------------------
RSA(MD5(签名数据),私钥)

你这个是什么意思?使用 RSA/MD5 进行签名的话一般使用 RSAWithMD5 数字签名算法!

帮你写了一个,基本上足够使用了。

Java code
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class Test {

    private final static char[] HEX = "0123456789abcdef".toCharArray();

    public static void main(String[] args) throws Exception {

        // 生成密钥对
        KeyPair pair = generateRandomRSAKeyPair(1024);

        // 获得私钥
        PrivateKey privateKey = pair.getPrivate();

        // 获得公钥
        PublicKey publicKey = pair.getPublic();

        // 获取公私钥对的字节数组,便于保存起来

        // 获取二进制格式的私钥
        byte[] privateKeyEnc = privateKey.getEncoded();
        // 获取二进制格式的公钥
        byte[] publicKeyEnc = publicKey.getEncoded();

        System.out.println("private key: " + toHex(privateKeyEnc));
        System.out.println(" public key: " + toHex(publicKeyEnc));

        // 从字节数组中恢复公私钥对
        KeyPair restorePair = restoreKeyPair(privateKeyEnc, publicKeyEnc, "RSA");

        System.out.println("private key: " + toHex(restorePair.getPrivate().getEncoded()));
        System.out.println(" public key: " + toHex(restorePair.getPublic().getEncoded()));

        String str = "abcdefg";

        // 数字签名
        byte[] sign = sign(str, restorePair.getPrivate(), "MD5WithRSA");
        System.out.println("签名值: " + toHex(sign));

        // 验证签名
        boolean verifyResult = verify(str, sign, restorePair.getPublic(), "MD5WithRSA");

        System.out.println("签名验证结果: " + verifyResult);
    }

    /**
     * <p>还原公私钥对</p>
     *
     * @param privateKeyEnc  私钥编码字节
     * @param publicKeyEnc  公钥编码字节
     * @param algorithm  非对称加密算法
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static KeyPair restoreKeyPair(byte[] privateKeyEnc, byte[] publicKeyEnc, String algorithm)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        return new KeyPair(restorePublicKey(publicKeyEnc, algorithm),
                restorePrivateKey(privateKeyEnc, algorithm));
    }

    /**
     * <p>通过字符数组还原私钥</p>
     *
     * @param privateKeyEnc 私钥的字节
     * @param algorithm 非对称加密算法
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PrivateKey restorePrivateKey(byte[] privateKeyEnc, String algorithm)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyEnc);
        KeyFactory factory = KeyFactory.getInstance(algorithm);
        return factory.generatePrivate(keySpec);
    }

    /**
     * <p>通过字符数组还原公钥</p>
     *
     * @param privateKeyEnc 公钥的字节
     * @param algorithm 非对称加密算法
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PublicKey restorePublicKey(byte[] publicKeyEnc, String algorithm)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeySpec keySpec = new X509EncodedKeySpec(publicKeyEnc);
        KeyFactory factory = KeyFactory.getInstance(algorithm);
        return factory.generatePublic(keySpec);
    }

    /**
     * <p>生成随机 RSA 密钥对</p>
     * @param keySize  RSA 密钥对长度
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static KeyPair generateRandomRSAKeyPair(int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
        gen.initialize(keySize);
        return gen.generateKeyPair();
    }

    /**
     * <p>数字签名</p>
     *
     * @param str 需要签名的字符串
     * @param privateKey 签名私钥
     * @param signatureAlgorithm 数字签名算法
     * @return
     * @throws Exception
     */
    public static byte[] sign(String str, PrivateKey privateKey, String signatureAlgorithm) throws Exception {
        Signature signature = Signature.getInstance(signatureAlgorithm);
        signature.initSign(privateKey);
        signature.update(str.getBytes("UTF-8"));
        return signature.sign();
    }

    /**
     * <p>验证签名</p>
     *
     * @param str  需要验证签名的字符串
     * @param sign 签名数据
     * @param publicKey  验证签名的公钥
     * @param signatureAlgorithm  数字签名算法
     * @return
     */
    public static boolean verify(String str, byte[] sign, PublicKey publicKey, String signatureAlgorithm) {
        try {
            Signature signature = Signature.getInstance(signatureAlgorithm);
            signature.initVerify(publicKey);
            signature.update(str.getBytes("UTF-8"));
            return signature.verify(sign);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * <p>将字节转换成为 HEX 字符</p>
     *
     * @param bys
     * @return
     */
    public static String toHex(byte[] bys) {
        char[] chs = new char[bys.length * 2];
        for (int i = 0, k = 0; i < bys.length; i++) {
            chs[k++] = HEX[(bys[i] >> 4) & 0xf];
            chs[k++] = HEX[bys[i] & 0xf];
        }
        return new String(chs);
    }
}