1

我正在尝试使用 AES/CBC 加密文件,密钥必须是随机的并使用 RSA 加密。我得到“算法 RSA 的密钥不适合对称加密。”......这似乎是什么问题?

这是我的代码的一部分:

    Security.addProvider(new BouncyCastleProvider());
    byte[] input = "Encryption Test".getBytes();
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC"); // init Cipher to use AES/CBC
    SecureRandom random = new SecureRandom(); // IV is random 
    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "BC"); // Key will be generated with RSA

    generator.initialize(512, random);
    KeyPair pair = generator.generateKeyPair();
    Key pubKey = pair.getPublic();
    //Key privKey = pair.getPrivate();

    cipher.init(Cipher.ENCRYPT_MODE, pubKey, random);
4

2 回答 2

1

恭喜您希望使用密钥交换密码进行密钥交换!有时我想知道为什么互联网上有这么多人试图将 RSA 变成流密码。

下面的示例代码向您展示了如何执行此操作。

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import java.io.*;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class Test {

    /**
     * Generate an RSA key pair and save it to the file
     */
    public static KeyPair genKeys(File keyFile) throws Exception {
        System.out.println("Generating RSA keys");

        KeyFactory factory = KeyFactory.getInstance("RSA");
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(2048);
        KeyPair kp = kpg.generateKeyPair();
        X509EncodedKeySpec pubSpec = factory.getKeySpec(kp.getPublic(),
                X509EncodedKeySpec.class);
        PKCS8EncodedKeySpec privSpec = factory.getKeySpec(kp.getPrivate(),
                PKCS8EncodedKeySpec.class);

        FileOutputStream out = new FileOutputStream(keyFile);
        DataOutputStream dat = new DataOutputStream(out);

        byte[] enc = pubSpec.getEncoded();
        dat.writeInt(enc.length);
        dat.write(enc);

        enc = privSpec.getEncoded();
        dat.writeInt(enc.length);
        dat.write(enc);
        dat.flush();
        dat.close();

        System.out.println("RSA keys saved to " + keyFile.getPath());

        return kp;
    }


    /**
     * Load an RSA key pair from the file
     */
    public static KeyPair loadKeys(File keyFile) throws Exception {
        System.out.println("Loading RSA keys");

        FileInputStream in = new FileInputStream(keyFile);
        DataInputStream dat = new DataInputStream(in);

        int len = dat.readInt();
        byte[] enc = new byte[len];
        dat.readFully(enc);
        X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(enc);

        len = dat.readInt();
        enc = new byte[len];
        dat.readFully(enc);
        PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(enc);

        dat.close();

        KeyFactory factory = KeyFactory.getInstance("RSA");
        PublicKey pub = factory.generatePublic(pubSpec);
        PrivateKey priv = factory.generatePrivate(privSpec);

        System.out.println("RSA keys loaded from " + keyFile.getPath());
        return new KeyPair(pub, priv);
    }


    /**
     * Decrypt a file
     */
    public static void decrypt(KeyPair kp, File inFile, File outFile) throws Exception {
        Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");

        FileInputStream in = new FileInputStream(inFile);
        DataInputStream dat = new DataInputStream(in);

        // read RSA encrypted AES key
        int len = dat.readInt();
        byte[] buf = new byte[len];
        dat.readFully(buf);
        rsa.init(Cipher.DECRYPT_MODE, kp.getPrivate());

        SecretKeySpec key = new SecretKeySpec(rsa.doFinal(buf), "AES");

        // read the AES IV
        len = dat.readInt();
        buf = new byte[len];
        dat.readFully(buf);
        IvParameterSpec iv = new IvParameterSpec(buf);

        Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aes.init(Cipher.DECRYPT_MODE, key, iv);

        // process the rest of the file to get the original back
        FileOutputStream out = new FileOutputStream(outFile);

        buf = new byte[1000];
        int r = -1;
        while( (r = dat.read(buf)) != -1 ) {
            byte[] sec = aes.update(buf, 0, r);
            if (sec != null) out.write(sec);
        }
        out.write(aes.doFinal());
        out.flush();
        out.close();
        in.close();
    }


    public static void encrypt(KeyPair kp, File inFile, File outFile) throws Exception {
        Cipher rsa = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");

        // create new AES key
        KeyGenerator gen = KeyGenerator.getInstance("AES");
        gen.init(256);
        SecretKey key = gen.generateKey();

        // RSA encrypt AES key
        byte[] keyEnc = key.getEncoded();
        rsa.init(Cipher.ENCRYPT_MODE, kp.getPublic());
        byte[] keySec = rsa.doFinal(keyEnc);

        // Create AES cipher
        Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aes.init(Cipher.ENCRYPT_MODE, key);
        byte[] iv = aes.getIV();

        FileOutputStream out = new FileOutputStream(outFile);
        DataOutputStream dat = new DataOutputStream(out);

        // save encrypted AES key and IV
        dat.writeInt(keySec.length);
        dat.write(keySec);
        dat.writeInt(iv.length);
        dat.write(iv);

        // save the encrypted file
        FileInputStream in = new FileInputStream(inFile);
        byte[] buf = new byte[1000];
        int r = -1;
        while( (r = in.read(buf)) != -1 ) {
            byte[] sec = aes.update(buf, 0, r);
            if (sec != null) dat.write(sec);
        }
        dat.write(aes.doFinal());
        dat.flush();
        dat.close();
        in.close();
    }


    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        if (args.length != 4) {
            System.out.println("Usage: java Test (encrpyt|decrypt) keyFile inFile outFile");
            return;
        }
        KeyPair kp;
        File keyFile = new File(args[0]);
        if (!keyFile.canRead()) {
            kp = genKeys(keyFile);
        } else {
            kp = loadKeys(keyFile);
        }

        boolean isEnc = args[1].equalsIgnoreCase("encrypt");
        boolean isDec = args[1].equalsIgnoreCase("decrypt");
        File inFile = new File(args[2]);
        File outFile = new File(args[3]);
        if (!(isEnc || isDec) || !inFile.canRead()) {
            System.out.println("Usage: java Test (encrpyt|decrypt) keyFile inFile outFile");
            return;
        }

        if (isEnc) {
            encrypt(kp, inFile, outFile);
        } else {
            decrypt(kp, inFile, outFile);
        }
    }
}
于 2013-01-05T00:48:29.940 回答
1

您不能将 RSA 密钥与 AES 密码一起使用...

改用这个:

 KeyGenerator keyGen = KeyGenerator.getInstance("AES", "BC");
 keyGen.init(256);
 Key key = keyGen.generateKey();

在这里你可以找到一个代码示例。

于 2013-01-04T22:59:42.233 回答