• Java利用MD5WithRSA签名及DESede加密


    前言:近期公司做数据加密及签名,整理如下:

    一、数字签名。

    是只有信息的发送者才能产生的别人无法伪造的一段数字串,具有不可抵赖性,可验证信息完整性的一种手段。

    签名不可伪造:其他人因为没有对应的私钥,所以没法生成公钥可以解密的密文,所以是不可伪造的。

    过程为:

    1.A对消息M计算摘要,得到摘要H(可以采用MD5,因为MD5具有唯一性且不可逆)。

    2.A利用自己的私钥对H进行签名得到Sign(即加密,可以采用RSA)

    二、消息加密

    可采用DESede算法进行加密,需要获取密钥对。

    三、消息加密,并进行签名

    1.A生成消息M。

    2.利用MD5加密M生成摘要H(就是生成16字节的散列值)。

    3.利用A的私钥(因为私钥保护的好是不可能外露的,加密后的消息是不可能被其他公钥解密的)对H进行加密,生成签名Sign。

    4.将M通过DESede进行加密,生成加密消息R。

    5.将Sign和R进行Base64编码后发送给B。

    四、解密

    1.解密消息R,生成原文P。

    2.利用A的公钥解密签名Sign生成B。

    3.对P进行MD5加密,并与B进行比较,如果一致说明没有被修改过。

    五、代码(以下代码已验证)

    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Signature;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import kh.pms.tools.StringUtil;
    
    /**
     * 签名验签及加密 1.对原文进行des加密。 2.des加密数据进行md5。 3.用我方私钥进行md5的签名。 4.用我方公钥对des加密数据进行加密
     * 
     * @author chx
     *
     */
    public class MD5withRSA {
        private static final String FLAG_RSA = "RSA";
        private static final String SIGNATURE_ALGORITHM = "MD5withRSA";
        /**
         * 我方私钥对象
         */
        private PrivateKey myPrivateKeyObj;
    
        /**
         * 银行方公钥对象
         */
        private PublicKey bankPublicKeyObj;
    
        /**
         * 获取签名
         * 
         * @return
         * @throws Exception
         */
        public byte[] getSign(String str) throws Exception {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);// 签名的算法
            signature.initSign(myPrivateKeyObj);
            signature.update(str.getBytes());
            return signature.sign();
        }
    
        /**
         * 析构函数
         * 
         * @param plain
         *            待加解密原文
         * @throws Exception
         */
        public MD5withRSA() throws Exception {
            myPrivateKeyObj = getPrivateKey();
          //将此处的JianHangUtil.bankPublicKey更换为自己的公钥字符串(base64格式),后面的 bankPublicKeyObj
    = getPublicKey(JianHangUtil.bankPublicKey); } /** * 通过预制公钥生成PublicKey * * @param pubKey * @return * @throws Exception */ private PublicKey getPublicKey(String key) throws Exception { byte[] encoded = StringUtil.getBaseStrJie(key); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded); KeyFactory factory = KeyFactory.getInstance(FLAG_RSA); return factory.generatePublic(keySpec); } /** * 将指定的字符串转换为私钥key * * @param priKey * @return * @throws Exception */ private PrivateKey getPrivateKey() throws Exception { // 首先进行base64解码。 byte[] encoded = StringUtil.getBaseStrJie(JianHangUtil.myPrivateKey); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); KeyFactory factory = KeyFactory.getInstance(FLAG_RSA); return factory.generatePrivate(keySpec); } /** * 验证签名 * * @param data * 原文 * @param mySign * 签名 * @return * @throws Exception */ public boolean yanZhengSign(byte[] data, byte[] mySign) throws Exception { Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(bankPublicKeyObj); signature.update(data); return signature.verify(mySign); }

    加解密:

    package kh.pms.bank;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESedeKeySpec;
    import kh.pms.tools.StringUtil;
    
    /**
     * 报文加解密工具(注意,本类所有方法均会进行base64解码)
     * 
     * @author chx
     *
     */
    public class DESedeCoder {
        /**
         * 密钥算法
         */
        private static String KEY_ALGORITHM = "DESede";
        private static String DEFAULT_CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";
    
        /**
         * 加密(会对des和公钥进行base64解码)
         * 
         * @param data
         *            待加密数据
         * @param key
         *            密钥
         * @return byte[] 加密数据
         * @throws Exception
         */
        public byte[] encrypt(byte[] src) throws Exception {
            DESedeKeySpec dks = new DESedeKeySpec(StringUtil.getBaseStrJie(JianHangUtil.desKey));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
            SecretKey securekey = keyFactory.generateSecret(dks);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, securekey);
            return cipher.doFinal(src);
        }
    
        /**
         * 解密
         * 
         * @param data
         *            待解密数据
         * @param key
         *            密钥
         * @return byte[] 解密数据
         * @throws Exception
         */
        public byte[] decrypt(byte[] data) throws Exception {
            // 加解密的deskey(需更换为自己的des密钥)
            DESedeKeySpec dks = new DESedeKeySpec(StringUtil.getBaseStrJie(JianHangUtil.desKey));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
            SecretKey securekey = keyFactory.generateSecret(dks);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, securekey);
            return cipher.doFinal(data);
        }
    }
  • 相关阅读:
    SpringRMI解析3-RmiServiceExporter逻辑细节
    SpringRMI解析2-RmiServiceExporter逻辑脉络
    SpringRMI解析1-使用示例
    SpringMVC解析5-DispatcherServlet逻辑细节
    SpringMVC解析4-DispatcherServlet逻辑脉络
    SpringMVC解析3-DispatcherServlet组件初始化
    SpringMVC解析2-ContextLoaderListener
    算法笔记_074:子集和问题(Java)
    算法笔记_073:哈密顿回路问题(Java)
    算法笔记_072:N皇后问题(Java)
  • 原文地址:https://www.cnblogs.com/chxwkx/p/11931681.html
Copyright © 2020-2023  润新知