如何从Base64生成的公钥加密文件

时间:2017-03-07 11:40:49

标签: java-8 base64 public-key-encryption java-security

我得到了使用公钥加密给定文件的任务,我必须从给定的Base64指数和模数生成公钥。我使用代码

生成了公钥
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;
import java.util.Base64;


/**
 *
 * @author Kunjesh RSA - Encrypt Data using Public Key RSA - Descypt Data using
 * Private Key
 */
public class RSAEncryption {

    private static final String PUBLIC_KEY_FILE = "Public.key";

    public static void main(String[] args) throws IOException {

        try {

            System.out.println("\n--------SAVING PUBLIC KEY AND PRIVATE KEY TO FILES-------\n");


            // Hardcode the RSA key

            String modulusString = "qSwYXXE+SQ/ROpCQazST9imW+mPSjiCSjF4s+TFsPpdVln+tL9LrFEVo2ok+97WNg8ZkTEO5atw7uN8FJFXnWAXpQuHBos9/m3Y31nwSaj+CbFr+qdCHFxAq+l7cJUZI7JCCG8GS2365rMBzMSHK0tHcqCNk/EzW+jsBvKumQ7E=";

            //String modulusString = "00d56047acf652298e3fcdbb8cecbc32214722aa1625f88480cf570cee373ada932b140c29b00dc44f6e59e7018dddca66b2f1c645dacb9d4a45459cfa8f7e33df";

            //String exponentString = "18bc01730656bde47476f7cfbd3d8f9e15ede9c389814672dc161e349b08627fc885fe9d2442ae92f0214c7e97cf0b9a9fc876df4f53517ab63d710f997b2779";

            String publicExponentString = "AQAB";


            // Load the key into BigIntegers

            BigInteger modulus = new BigInteger(Base64.getDecoder().decode(modulusString));

            //BigInteger exponent = new BigInteger(exponentString, 16);

            BigInteger pubExponent = new BigInteger(Base64.getDecoder().decode(publicExponentString));


            // Create private and public key specs

            //RSAPrivateKeySpec privateSpec = new RSAPrivateKeySpec(modulus, exponent);

            RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(modulus, pubExponent);


            // Create a key factory

            KeyFactory factory = KeyFactory.getInstance("RSA");

            System.out.println("Hello world");


           // Create the RSA private and public keys

           // PrivateKey priv = factory.generatePrivate(privateSpec);

            PublicKey pub = factory.generatePublic(publicSpec);

            RSAEncryption rsaObj = new RSAEncryption();

            rsaObj.saveKey(PUBLIC_KEY_FILE, modulus, pubExponent);

        } catch (Exception e) {
        }
    }


    private void saveKey(String fileName, BigInteger mod, BigInteger exp) throws IOException {

        System.out.println("Hello World");

        FileOutputStream fos = null;

        ObjectOutputStream oos = null;

        try {

            System.out.println("Generating " + fileName + "...");
            fos = new FileOutputStream(fileName);
            oos = new ObjectOutputStream(new BufferedOutputStream(fos));
            oos.writeObject(mod);
            oos.writeObject(exp);

            System.out.println(fileName + " generated successfully");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                oos.close();
                if (fos != null) {
                    fos.close();
                }
            }
        }
    }
}

公钥已成功生成。但是当我使用此代码生成的密钥加密给定文件时

public void encryptFile(String inputFileName, String outputFileName, String keyFileName) throws Exception {
        try {
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            SecureRandom random = new SecureRandom();
            keygen.init(random);

            SecretKey key = keygen.generateKey();

            //Packages with the RSA public key
            System.out.println("keyFileName : " + keyFileName);
            ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(keyFileName));
            Key publicKey = (Key) keyIn.readObject();
            keyIn.close();

            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.WRAP_MODE, publicKey);

            byte[] wrappedKey = cipher.wrap(key);
            DataOutputStream out = new DataOutputStream(new FileOutputStream(outputFileName));
            out.writeInt(wrappedKey.length);
            out.write(wrappedKey);

            InputStream in = new FileInputStream(inputFileName);
            cipher = cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, key);

            crypt(in, out, cipher);
            in.close();
            out.close();
        } catch (Exception e) {
            System.out.println("++++ Exception encryptFile ++++");
            e.printStackTrace();
            throw e;
        }
}

private void crypt(InputStream in, OutputStream out, Cipher cipher)
            throws IOException, GeneralSecurityException {

        System.out.println("in inside crypt ---- " + in);
        System.out.println("in inside crypt ---- " + out);
        System.out.println("cipher inside crypt  ----- " + cipher);

        int blockSize = cipher.getBlockSize();
        int outputSize = cipher.getOutputSize(blockSize);
        byte[] inBytes = new byte[blockSize];
        byte[] outBytes = new byte[outputSize];

        int inLength = 0;
        boolean done = false;

        while (!done) {
            inLength = in.read(inBytes);

            if (inLength == blockSize) {
                int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
                out.write(outBytes, 0, outLength);
            } else {
                done = true;
            }
        }


        if (inLength > 0) {
            outBytes = cipher.doFinal(inBytes, 0, inLength);
        } else {
            outBytes = cipher.doFinal();
        }

        out.write(outBytes);
}

显示错误

java.lang.ClassCastException:java.math.BigInteger无法强制转换为java.security.Key

java.lang.ClassCastException发生异常:java.math.BigInteger无法强制转换为java.security.Key

我哪里错了?救救我..

1 个答案:

答案 0 :(得分:0)

您无法直接将BigInteger投射到KeyKey应该由两个BigInteger s,模数和指数构成。试试这个:

RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, publicExponent);
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey pub = factory.generatePublic(spec);