• Bouncycastle中的RSA技术以及解决之道


    一个使用bouncycastle进行安全操作的实用类

    2007-04-13 12:54

    import java.io.*;
    import java.security.*;
    import java.security.interfaces.*;
    import java.math.*;
    import java.util.Enumeration;
    import java.util.Vector;

    import org.bouncycastle.crypto.AsymmetricBlockCipher;
    import org.bouncycastle.crypto.encodings.PKCS1Encoding;
    import org.bouncycastle.crypto.engines.RSAEngine;
    import org.bouncycastle.crypto.params.RSAKeyParameters;
    import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
    import org.bouncycastle.util.encoders.Hex;

    public class RSAUtil {

        final public static int RAW = 1;
        final public static int PKCS1 = 2;

        /*
        * 产生RSA公私钥对
        */
        public static KeyPair genRSAKeyPair() {
            KeyPairGenerator rsaKeyGen = null;
            KeyPair rsaKeyPair = null;
            try {
                System.out.println("Generating a pair of RSA key ... ");
                rsaKeyGen = KeyPairGenerator.getInstance("RSA");
                SecureRandom random = new SecureRandom();
                random.nextBytes(new byte[1]);
                rsaKeyGen.initialize(1024, new SecureRandom());
                rsaKeyPair = rsaKeyGen.genKeyPair();
                PublicKey rsaPublic = rsaKeyPair.getPublic();
                PrivateKey rsaPrivate = rsaKeyPair.getPrivate();
                System.out.println("1024-bit RSA key GENERATED.");
            } catch (Exception e) {
                System.out.println("Exception in keypair generation. Reason: " + e);
            }

            return rsaKeyPair;
        }

        /*
        * 列出密钥库中指定的条目
        */
        public static void showAllEntry(String filename, String pass) {
            try {
                FileInputStream inKeyStoreFile = new FileInputStream(filename);
                char[] password = pass.toCharArray();
                KeyStore from = KeyStore.getInstance("JKS", "SUN");
                from.load(null, null);
                from.load(inKeyStoreFile, password);
                Enumeration e = from.aliases();
                System.out.println("Entry List:");
                while (e.hasMoreElements()) {
                    System.out.println((String) e.nextElement());
                }
                inKeyStoreFile.close();
            } catch (Exception e) {
                System.out.println(e);
            }
        }

        /*
        * 列出密钥库中所有的条目
        */
        public static Vector getAllEntry(String filename, String pass) {
            Vector v = new Vector();
            try {
                FileInputStream inKeyStoreFile = new FileInputStream(filename);
                char[] password = pass.toCharArray();
                KeyStore from = KeyStore.getInstance("JKS", "SUN");
                from.load(null, null);
                from.load(inKeyStoreFile, password);
                Enumeration e = from.aliases();
                System.out.println("Entry List:");
                while (e.hasMoreElements()) {
                    v.addElement((String) e.nextElement());

                }
                inKeyStoreFile.close();
                return v;
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }
        }

        /*
        * 获得私钥
        */
        public static RSAPrivateKey loadPrivateKey(String filename, String keyName,
                String pass) throws Exception {
            FileInputStream inKeyStoreFile = new FileInputStream(filename);
            char[] password = pass.toCharArray();
            KeyStore from = KeyStore.getInstance("JKS", "SUN");
            from.load(null, null);
            from.load(inKeyStoreFile, password);
            Key testkey = from.getKey(keyName, password);
            RSAPrivateKey pvtKey = (RSAPrivateKey) testkey;
            System.out.println("Private key exponent = "
                    + pvtKey.getPrivateExponent().toString(16) + " ");
            inKeyStoreFile.close();
            return pvtKey;
        }

        /*
        * 获得公钥
        */
        public static RSAPublicKey loadPublicKey(String filename, String keyName,
                String pass) throws Exception {
            FileInputStream inKeyStoreFile = new FileInputStream(filename);
            char[] password = pass.toCharArray();
            KeyStore from = KeyStore.getInstance("JKS", "SUN");
            from.load(null, null);
            from.load(inKeyStoreFile, password);
            java.security.cert.Certificate c = from.getCertificate(keyName);
            RSAPublicKey pubKey = (RSAPublicKey) c.getPublicKey();
            System.out.println("Public key exponent = "
                    + pubKey.getPublicExponent().toString(16) + " ");
            inKeyStoreFile.close();
            return pubKey;
        }

        /*
        * 使用公钥加密
        */
        public static byte[] rsaPubEncrypt(RSAPublicKey PubKey, byte[] clearBytes,
                int type) {

            BigInteger mod = PubKey.getModulus();
            BigInteger pubExp = PubKey.getPublicExponent();

            RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod,
                    pubExp);

            System.out.println("mod: " + mod.toString(16));
            System.out.println("pubExp: " + pubExp.toString(16));
            AsymmetricBlockCipher eng = new RSAEngine();
            if (type == PKCS1)
                eng = new PKCS1Encoding(eng);
            eng.init(true, pubParameters);
            byte[] data = null;
            try {
                System.out.println("clearBytes: "
                        + new String(Hex.encode(clearBytes)));
                data = eng.processBlock(clearBytes, 0, clearBytes.length);
                System.out.println("EncBytes: " + new String(Hex.encode(data)));
                return data;
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }
        }

        /*
        * 公钥解密
        */
        public static byte[] rsaPubDecrypt(RSAPublicKey PubKey, byte[] clearBytes,
                int type) {

            BigInteger mod = PubKey.getModulus();
            BigInteger pubExp = PubKey.getPublicExponent();

            RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod,
                    pubExp);

            System.out.println("mod: " + mod.toString(16));
            System.out.println("pubExp: " + pubExp.toString(16));
            AsymmetricBlockCipher eng = new RSAEngine();
            if (type == PKCS1)
                eng = new PKCS1Encoding(eng);
            eng.init(false, pubParameters);
            byte[] data = null;
            try {
                System.out.println("clearBytes: "
                        + new String(Hex.encode(clearBytes)));
                data = eng.processBlock(clearBytes, 0, clearBytes.length);
                System.out.println("EncBytes: " + new String(Hex.encode(data)));
                return data;
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }
        }

        /*
        * 私钥解密
        */
        public static byte[] rsaPriDecrypt(RSAPrivateKey prvKeyIn,
                byte[] encodedBytes, int type) {

            RSAPrivateCrtKey prvKey = (RSAPrivateCrtKey) prvKeyIn;

            BigInteger mod = prvKey.getModulus();
            BigInteger pubExp = prvKey.getPublicExponent();
            BigInteger privExp = prvKey.getPrivateExponent();
            BigInteger pExp = prvKey.getPrimeExponentP();
            BigInteger qExp = prvKey.getPrimeExponentQ();
            BigInteger p = prvKey.getPrimeP();
            BigInteger q = prvKey.getPrimeQ();
            BigInteger crtCoef = prvKey.getCrtCoefficient();

            RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(mod,
                    pubExp, privExp, p, q, pExp, qExp, crtCoef);

            AsymmetricBlockCipher eng = new RSAEngine();
            if (type == PKCS1)
                eng = new PKCS1Encoding(eng);

            eng.init(false, privParameters);
            byte[] data = null;
            try {
                data = eng.processBlock(encodedBytes, 0, encodedBytes.length);
                return data;
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }

        }

        /*
        * 使用私钥加密
        */
        public static byte[] rsaPriEncrypt(RSAPrivateKey prvKeyIn,
                byte[] encodedBytes, int type) {
            RSAPrivateCrtKey prvKey = (RSAPrivateCrtKey) prvKeyIn;
            BigInteger mod = prvKey.getModulus();
            BigInteger pubExp = prvKey.getPublicExponent();
            BigInteger privExp = prvKey.getPrivateExponent();
            BigInteger pExp = prvKey.getPrimeExponentP();
            BigInteger qExp = prvKey.getPrimeExponentQ();
            BigInteger p = prvKey.getPrimeP();
            BigInteger q = prvKey.getPrimeQ();
            BigInteger crtCoef = prvKey.getCrtCoefficient();
            RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(mod,
                    pubExp, privExp, p, q, pExp, qExp, crtCoef);
            AsymmetricBlockCipher eng = new RSAEngine();
            if (type == PKCS1)
                eng = new PKCS1Encoding(eng);
            eng.init(true, privParameters);
            byte[] data = null;
            try {
                data = eng.processBlock(encodedBytes, 0, encodedBytes.length);
                return data;
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }

        }

    问题所在:

    本系统采用的是RSA签名验证方案。采用PKCS1填充方案。

    RSAPublicKey 和RSAPrivateKey 在BC中无该类,故研究发现:

    RSAPublicKey可采用BC中的RSAKeyParameters,RSAPrivateKey可采用修改BC中的RSAPrivateCrtKeyParameter;主要修改其中的mod和privateExp;

    并增加其getter和setter方法。以便于采用私钥参数加密。

  • 相关阅读:
    一种C#读写二进制文件的通用方法
    关于POP3协议的一点资料
    关于看图工具的几点想法
    在WPF程序中将控件所呈现的内容保存成图像
    Nuget挂了的解决方法
    VisualStudio 2012中的单元测试
    在Andorid平板上体验Windows8的猜想
    创建自己的awaitable类型
    【转载】:最佳注释
    百度云盘试用
  • 原文地址:https://www.cnblogs.com/adylee/p/3625389.html
Copyright © 2020-2023  润新知