rsa解密密码的长度小于8,填充错误

时间:2014-02-24 07:27:35

标签: java rsa

package net.pusuo.java.security;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
* RSA加密解密工具类
* User: shijinkui
* Date: 14-2-24
* Time: 上午11:20
* To change this template use File | Settings | File Templates.
*/
public class RSAUtil {
public static final String KEY_ALGORTHM = "RSA";
public static final String CIPHER_ALGORTHM = "RSA/ECB/PKCS1Padding";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

private static RSAPublicKey publicKey;
private static RSAPrivateKey privateKey;

static {
    initKey();
}

/**
 * 初始化密钥
 *
 * @return
 * @throws Exception
 */
public static void initKey() {
    KeyPairGenerator keyPairGenerator;
    try {
        keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORTHM);
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        publicKey = (RSAPublicKey) keyPair.getPublic();
        privateKey = (RSAPrivateKey) keyPair.getPrivate();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}


/**
 * 取得公钥,并转化为String类型
 *
 * @return
 * @throws Exception
 */
public static String getPublicKey() throws Exception {
    return base64Encode(publicKey.getEncoded());
}

/**
 * 取得私钥,并转化为String类型
 *
 * @return
 * @throws Exception
 */
public static String getPrivateKey() throws Exception {
    return base64Encode(privateKey.getEncoded());
}

/**
 * BASE64解密
 *
 * @param key
 * @return
 * @throws Exception
 */
public static byte[] base64Decode(String key) throws Exception {
    return Base64.decodeBase64(key);
}

/**
 * BASE64加密
 *
 * @param key
 * @return
 * @throws Exception
 */
public static String base64Encode(byte[] key) throws Exception {
    return Base64.encodeBase64String(key);
}

/**
 * 用私钥加密
 *
 * @param plainText 加密数据
 * @return
 * @throws Exception
 */
public static String encryptByPrivateKey(String plainText) throws Exception {
    byte[] encodedData = base64Decode(plainText);
    byte[] ret = rsaByPrivateKey(encodedData, Cipher.ENCRYPT_MODE);
    return base64Encode(ret);
}

/**
 * 用私钥解密
 *
 * @return
 * @throws Exception
 */
public static String decryptByPrivateKey(String data) throws Exception {
    byte[] encodedData = base64Decode(data);
    byte[] ret = rsaByPrivateKey(encodedData, Cipher.DECRYPT_MODE);

    return base64Encode(ret);
}

public static byte[] rsaByPrivateKey(byte[] data, int mode) throws Exception {
    byte[] keyBytes = privateKey.getEncoded();

    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
    Key privateKey2 = keyFactory.generatePrivate(keySpec);

    Cipher cipher = Cipher.getInstance(CIPHER_ALGORTHM);
    cipher.init(mode, privateKey2);

    return cipher.doFinal(data, 0, data.length);
}


/**
 * 用公钥加密
 *
 * @param data 加密数据
 * @return
 * @throws Exception
 */
public static String encryptByPublicKey(String data) throws Exception {
    byte[] encodedData = base64Decode(data);
    byte[] ret = rsaByPublicKey(encodedData, Cipher.ENCRYPT_MODE);
    return base64Encode(ret);
}

/**
 * 用公钥解密
 *
 * @param data 加密数据
 * @return
 * @throws Exception
 */
public static String decryptByPublicKey(String data) throws Exception {
    byte[] base64Data = base64Decode(data);
    byte[] ret = rsaByPublicKey(base64Data, Cipher.DECRYPT_MODE);
    return base64Encode(ret);
}

public static byte[] rsaByPublicKey(byte[] data, int mode) throws Exception {
    byte[] keyBytes = publicKey.getEncoded();
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);
    Key publicKey = keyFactory.generatePublic(keySpec);

    Cipher cipher = Cipher.getInstance(CIPHER_ALGORTHM);
    cipher.init(mode, publicKey);

    return cipher.doFinal(data, 0, data.length);
}


/**
 * 用私钥对信息生成数字签名
 *
 * @param data 要加密数据
 * @return
 * @throws Exception
 */
public static String sign(byte[] data) throws Exception {
    byte[] keyBytes = privateKey.getEncoded();
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);    //构造PKCS8EncodedKeySpec对象
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);       //指定加密算法
    PrivateKey privateKey2 = keyFactory.generatePrivate(keySpec);       //取私钥匙对象

    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);   //用私钥对信息生成数字签名
    signature.initSign(privateKey2);
    signature.update(data);

    return base64Encode(signature.sign());
}

/**
 * 校验数字签名
 *
 * @param data 加密数据
 * @param sign 数字签名
 * @return
 * @throws Exception
 */
public static boolean verify(byte[] data, String sign) throws Exception {
    byte[] keyBytes = publicKey.getEncoded();
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);  //构造X509EncodedKeySpec对象
    KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORTHM);   //指定加密算法
    PublicKey publicKey2 = keyFactory.generatePublic(keySpec);      //取公钥匙对象

    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
    signature.initVerify(publicKey2);
    signature.update(data);

    //验证签名是否正常
    return signature.verify(base64Decode(sign));
}

private static void test() throws Exception {
    String str = "1234";
    for (int i = 0; i < 1000000; i++) {
        String r1 = encryptByPrivateKey(str + i);
        String d1 = decryptByPublicKey(r1);
        String r2 = encryptByPublicKey(str + i);
        String d2 = decryptByPrivateKey(r2);

        System.out.println(str + i + ", 公钥解密:" + d1 + "||私钥解密:" + d2);
    }
}

public static void main(String[] args) throws Exception {
//      test();
    String str = "11";
    String r1 = encryptByPrivateKey(str);
    String d1 = decryptByPublicKey(r1);
    System.out.println(r1);
    System.out.println(d1);
}

}

输出:

PA / 9trxWBTGXvgk0SzFWMx9VjXMWwLppawqOtc6GVhcjNN0UV2pTPsE / Z3MIZ + VabBjSQ4DTsBDVDh2REWHe1Uswn2KiGv4C1bY58x3LkABG5uWODANlQM9A / LDlTTpPDUGsYxJf / CaI7W0hhNWaKcZyXiNmYVrmhfXfeej2F2U = 1瓦特==

密码为11,解密后为:1w == 为什么,我怎么能不使用填充模式? 感谢。

0 个答案:

没有答案