我要解决的问题是:
我把一个文件a.cfg加密后生成另外的一个文件b.cfg。现在我已经加密完了。但是我在解密时候遇到了问题:解不开了。
我用的是RSAUtil.class这个类。
我的加密过程是:先生成密钥对儿,用RSAUtil.encrypt(priKey, orgData)加密,生成另外的一个文件。同时把密钥保存在key.cfg里,在解密的时候,从key.cfg读密钥进行解密,但是没解开。RSAUtil.class这个类的用法我看了,它的例子里的方法是在加密之后马上进行解密,但是我要的不是这样的,我要是对这个文件加密后,以后再进行解密。
哪位兄弟用过RSA算法,能不能把加解密的过程说一下。

解决方案 »

  1.   

    这几天我也是正在折腾RSA算法的问题,楼主用的JCE是SUN提供的那个吗?
      

  2.   

    我的JCE 在bcprov-jdk14-128.jar包里,不知道是不是。:-(
      

  3.   

    兄弟,按你说的,应该不会错,你能把你的代码贴出来吗,我也搞了很长时间的对称算法加密,.NET和Java平台下交叉加减密,还比较了解(DES,TripleDES,RSA),贴出你的代码,让我帮你看看。
      

  4.   

    生成密钥的方法:
    public void createKey(){
    try{
            KeyPair keyPair = RSAUtil.generateKeyPair();
             pubKey = (RSAPublicKey) keyPair.getPublic();
             priKey = (RSAPrivateKey) keyPair.getPrivate();        byte[] pubModBytes = pubKey.getModulus().toByteArray();
            byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
            byte[] priModBytes = priKey.getModulus().toByteArray();
            byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
             //recoveryPubKey = RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
             //recoveryPriKey = RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);
            //String pubmod = recoveryPubKey.toString();
            //System.out.println( pubKey.getModulus());
             PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("key.cfg")));
             //out.println(recoveryPubKey);
             out.println(pubKey.getModulus());
             out.println(pubKey.getPublicExponent());
             out.println(priKey.getModulus());
             out.println(priKey.getPrivateExponent());
             out.close();
    }
    catch(Exception e){
    System.out.println("生成密钥失败!");
    }
    }加密并生成另外的一个文件:
    public void encrypt(){
    try{
            File file = new File("db.cfg");
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            byte[] tmpbuf = new byte[1024];
            int count = 0;
            while ((count = in.read(tmpbuf)) != -1) {
                bout.write(tmpbuf, 0, count);
                tmpbuf = new byte[1024];
            }
            in.close();
            byte[] orgData = bout.toByteArray();
            byte[] raw = RSAUtil.encrypt(priKey, orgData);
            file = new File("encrypt.cfg");
            OutputStream out = new FileOutputStream(file);
            out.write(raw);
            out.close();
    }
    catch(Exception e){

    }
    }解密:
    public void decrypt(){
    try{

            //读加密后的文件
            File file = new File("encrypt.cfg");
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            byte[] tmpbuf = new byte[1024];
            int count = 0;
            while ((count = in.read(tmpbuf)) != -1) {
                bout.write(tmpbuf, 0, count);
                tmpbuf = new byte[1024];
            }
            in.close();
            byte[] orgData = bout.toByteArray(); ///////////////////////////////////////////////////////////读密钥
            FileReader myFileReader=new FileReader("key.cfg");        BufferedReader myBufferedReader=new BufferedReader(myFileReader);
             
            String[] myStringArray=new String[4];
            String myString = null;
            int i = 0;        while((myString = myBufferedReader.readLine())!=null) { 
             myStringArray[i] =  myString;
             i++;
             }
            myFileReader.close();
            ////////////////////////////////////////////////////////////生成解密用的密钥
    byte[] pubModBytes = myStringArray[0].getBytes();
    byte[] pubPubExpBytes =myStringArray[1].getBytes();
    recoveryPubKey = RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);

            //byte[] priModBytes = myStringArray[2].getBytes();
            //byte[] priPriExpBytes = myStringArray[3].getBytes();
            //recoveryPriKey = RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);
            
            ////////////////////////////////////////////////////////
            byte[] data = RSAUtil.decrypt(recoveryPubKey, orgData);
            
            file = new File("decrypt.cfg");
            OutputStream out = new FileOutputStream(file);
            out.write(orgData);
            out.close();
    }
    catch(Exception e){
    System.out.println("解密时出现错误!"+e.toString());

    }
    }
      

  5.   

    楼上的兄弟,我用的是这些类来实现的:
    import java.security.Key;
    import javax.crypto.Cipher;
    import java.security.KeyPairGenerator;
    import java.security.KeyPair;没有用过RSAUtil类,抱歉,RSAUtil这个类是哪个包里的?
      

  6.   

    to  linuxyf(率人):
    能否帖一下你的rsa算法程序?
      

  7.   

    你参考一下这个吧:
    http://www.cs.princeton.edu/introcs/79crypto/RSA.java.html
    我以前实现的,在公司的服务器上,不便上传。
      

  8.   

    import javax.crypto.Cipher;
    import java.security.*;
    import java.security.spec.RSAPublicKeySpec;
    import java.security.spec.RSAPrivateKeySpec;
    import java.security.spec.InvalidKeySpecException;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.io.*;
    import java.math.BigInteger;/**
     * RSA 工具类。提供加密,解密,生成密钥对等方法。
     */ 
    public class RSAUtil {    /**
         * 生成密钥对
         * @return KeyPair
         * @throws EncryptException
         */
        public static KeyPair generateKeyPair() throws EncryptException {
            try {
                KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
                        new org.bouncycastle.jce.provider.BouncyCastleProvider());
                final int KEY_SIZE = 1024;//没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
                keyPairGen.initialize(KEY_SIZE, new SecureRandom());
                KeyPair keyPair = keyPairGen.genKeyPair();
                return keyPair;
            } catch (Exception e) {
                throw new EncryptException(e.getMessage());
            }
        }
        /**
         * 生成公钥
         * @param modulus
         * @param publicExponent
         * @return RSAPublicKey
         * @throws EncryptException
         */
        public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws EncryptException {
            KeyFactory keyFac = null;
            try {
                keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            } catch (NoSuchAlgorithmException ex) {
                throw new EncryptException(ex.getMessage());
            }        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));
            try {
                return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
            } catch (InvalidKeySpecException ex) {
                throw new EncryptException(ex.getMessage());
            }
        }
        /**
         * 生成私钥
         * @param modulus
         * @param privateExponent
         * @return RSAPrivateKey
         * @throws EncryptException
         */
        public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws EncryptException {
            KeyFactory keyFac = null;
            try {
                keyFac = KeyFactory.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
            } catch (NoSuchAlgorithmException ex) {
                throw new EncryptException(ex.getMessage());
            }        RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));
            try {
                return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
            } catch (InvalidKeySpecException ex) {
                throw new EncryptException(ex.getMessage());
            }
        }
        /**
         * 加密
         * @param key 加密的密钥
         * @param data 待加密的明文数据
         * @return 加密后的数据
         * @throws EncryptException
         */
        public static byte[] encrypt(Key key, byte[] data) throws EncryptException {
            try {
                Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
                cipher.init(Cipher.ENCRYPT_MODE, key);
                int blockSize = cipher.getBlockSize();//获得加密块大小,如:加密前数据为128个byte,而key_size=1024 加密块大小为127 byte,加密后为128个byte;因此共有2个加密块,第一个127 byte第二个为1个byte
                int outputSize = cipher.getOutputSize(data.length);//获得加密块加密后块大小
                int leavedSize = data.length % blockSize;
                int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
                byte[] raw = new byte[outputSize * blocksSize];
                int i = 0;
                while (data.length - i * blockSize > 0) {
                    if (data.length - i * blockSize > blockSize)
                        cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
                    else
                        cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
    //这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了OutputSize所以只好用dofinal方法。                i++;
                }
                return raw;
            } catch (Exception e) {
                throw new EncryptException(e.getMessage());
            }
        }
        /**
         * 解密
         * @param key 解密的密钥
         * @param raw 已经加密的数据
         * @return 解密后的明文
         * @throws EncryptException
         */
        public static byte[] decrypt(Key key, byte[] raw) throws EncryptException {
            try {
                Cipher cipher = Cipher.getInstance("RSA", new org.bouncycastle.jce.provider.BouncyCastleProvider());
                cipher.init(cipher.DECRYPT_MODE, key);
                int blockSize = cipher.getBlockSize();
                ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
                int j = 0;            while (raw.length - j * blockSize > 0) {
                    bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
                    j++;
                }
                return bout.toByteArray();
            } catch (Exception e) {
                throw new EncryptException(e.getMessage());
            }
        }
        /**
         *
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {
            File file = new File("db.cfg");
            FileInputStream in = new FileInputStream(file);
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            byte[] tmpbuf = new byte[1024];
            int count = 0;
            while ((count = in.read(tmpbuf)) != -1) {
                bout.write(tmpbuf, 0, count);
                tmpbuf = new byte[1024];
            }
            in.close();
            byte[] orgData = bout.toByteArray();        KeyPair keyPair = RSAUtil.generateKeyPair();//生成密钥对
            RSAPublicKey pubKey = (RSAPublicKey) keyPair.getPublic();//取公用密钥
            RSAPrivateKey priKey = (RSAPrivateKey) keyPair.getPrivate();//取私用密钥        byte[] pubModBytes = pubKey.getModulus().toByteArray();
            byte[] pubPubExpBytes = pubKey.getPublicExponent().toByteArray();
            byte[] priModBytes = priKey.getModulus().toByteArray();
            byte[] priPriExpBytes = priKey.getPrivateExponent().toByteArray();
            RSAPublicKey recoveryPubKey = RSAUtil.generateRSAPublicKey(pubModBytes,pubPubExpBytes);
            RSAPrivateKey recoveryPriKey = RSAUtil.generateRSAPrivateKey(priModBytes,priPriExpBytes);
            byte[] raw = RSAUtil.encrypt(priKey, orgData);
            file = new File("db2.cfg");
            OutputStream out = new FileOutputStream(file);
            out.write(raw);
            out.close();
            byte[] data = RSAUtil.decrypt(recoveryPubKey, raw);
            file = new File("db3.cfg");
            out = new FileOutputStream(file);
            out.write(data);
            out.flush();
            out.close();
        }
    }