RSA算法小结

RSA的三个重要大数分别为公钥指数e、私钥指数d和模值n。

RSA密钥对是由(公钥指数e+模值n)、(私钥指数d+模值n)组成。

RSA密钥的长度是指模值的bit数,通常的长度有768,1024,2048、3072、4096...

常用的公钥指数为1或65537。

RSA算法对明文长度存在要求。若超过最大长度,将抛出异常。

密文长度固定,等于模长。

如果不padding,则明文最大长度为模值长度。

如果存在padding,那么RSA_PKCS1_PADDING模式下, 明文最大长度为模值长度-11字节。该模式为默认模式。

如果存在padding,那么RSA_PKCS1_OAEP_PADDING模式下, 明文最大长度为模值长度-41字节。

虽然明文长度受Padding模式影响,但每次加密的block长度都为模值长度。

对于NO_PADDING的情况,若密文长度小于模值长度,则在明文前端加0x00,解密时并不把0x00自动删除。

JAVA RSA工具类

package com.breakloop.common;

import javax.crypto.Cipher;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.*;

public class RSAUtil {
    public static final int KEY_BIT_LENGTH_4096=4096;
    public static final int KEY_BIT_LENGTH_3072=3072;
    public static final int KEY_BIT_LENGTH_2048=2048;
    public static final int KEY_BIT_LENGTH_1024=1024;
    public static final int KEY_BIT_LENGTH_768=768;

    private static final String ALGO_CIPHER="RSA/ECB/NoPadding";

    private static final String SIGN_ALGORITHMS="SHA1WithRSA";

    public static KeyPair generateRSAKeyPair(int keyBitLength){
        KeyPair keyPair=null;
        try {
            KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(keyBitLength,new SecureRandom());
            keyPair=keyPairGenerator.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyPair;
    }

    public static byte[] getRSAPubKey(KeyPair keyPair){
        RSAPublicKey publicKey=(RSAPublicKey)keyPair.getPublic();
        return publicKey.getEncoded();
    }

    public static byte[] getRSAPriKey(KeyPair keyPair){
        RSAPrivateKey privateKey=(RSAPrivateKey)keyPair.getPrivate();
        return privateKey.getEncoded();
    }

    public static PublicKey getPublicKey(byte[] encoded){
        KeyFactory keyFactory = null;
        PublicKey publicKey=null;

        try {
            keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(
                    encoded);
            publicKey = keyFactory.generatePublic(bobPubKeySpec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }

        return publicKey;
    }

    public static PrivateKey getPrivateKey(byte[] encoded){
        KeyFactory keyFactory;
        PrivateKey privateKey=null;

        try {
            keyFactory = KeyFactory.getInstance("RSA");
            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
                    encoded);
            privateKey = keyFactory.generatePrivate(priPKCS8);

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }

        return privateKey;
    }

    public static PublicKey getPublicKey(byte[] modulus, byte[] exponent){
        BigInteger bigIntegerModulus=new BigInteger(modulus);
        BigInteger bigIntegerExponent=new BigInteger(exponent);
        RSAPublicKeySpec keySpec=new RSAPublicKeySpec(bigIntegerModulus,bigIntegerExponent);
        KeyFactory keyFactory= null;
        PublicKey publicKey= null;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
            publicKey = keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return publicKey;
    }

    public static PrivateKey getPrivateKey(byte[] modulus, byte[] exponent){
        BigInteger bigIntegerModulus=new BigInteger(modulus);
        BigInteger bigIntegerExponent=new BigInteger(exponent);
        RSAPrivateKeySpec keySpec=new RSAPrivateKeySpec(bigIntegerModulus,bigIntegerExponent);
        KeyFactory keyFactory= null;
        PrivateKey privateKey= null;
        try {
            keyFactory = KeyFactory.getInstance("RSA");
            privateKey = keyFactory.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return privateKey;
    }

    public static byte[] encrypt(PublicKey publicKey, byte[] data) {
        if (publicKey != null) {
            try {
                Cipher cipher = Cipher.getInstance(ALGO_CIPHER);
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                return cipher.doFinal(data);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static byte[] decrypt(PrivateKey privateKey, byte[] raw) {
        if (privateKey != null) {
            try {
                Cipher cipher = Cipher.getInstance(ALGO_CIPHER);
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                return cipher.doFinal(raw);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    public static byte[] cipher(Key key,byte[] data,boolean isEncrypt){
        try {
            Cipher cipher = Cipher.getInstance(ALGO_CIPHER);
            cipher.init(isEncrypt?Cipher.ENCRYPT_MODE:Cipher.DECRYPT_MODE, key);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static boolean verify(byte[] content, byte[] sign, byte[] pubModulus, byte[] pubExponent) {
        try {
            PublicKey pubKey = getPublicKey(pubModulus,pubExponent);
            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
            signature.initVerify(pubKey);
            signature.update( content );
            return signature.verify(sign);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    public static byte[] sign(byte[] content, byte[] priModulus, byte[] priExponent) {
        try {
            PrivateKey priKey = getPrivateKey(priModulus,priExponent);
            Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
            signature.initSign(priKey);
            signature.update( content);
            byte[] signed = signature.sign();
            return signed;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

参考博文:

http://blog.csdn.net/lvxiangan/article/details/45487943

http://blog.csdn.net/luoluo_onion/article/details/78354799

https://www.cnblogs.com/lzl-sml/p/3501447.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值