解密后的字符串与预加密字符串不同

时间:2012-07-04 13:23:46

标签: java file encryption rsa

我有以下代码:

全局

public static PublicKey pubKey;
public static PrivateKey privKey;
public static Cipher cip;

主要

public static void main(String[] args) throws Exception {
    //Generate the keys

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(1024);
    KeyPair kp = kpg.genKeyPair();
    Key publicKey = kp.getPublic();
    Key privateKey = kp.getPrivate();

    KeyFactory fact = KeyFactory.getInstance("RSA");
    cip = Cipher.getInstance("RSA/ECB/NoPadding");

    // Store Public Key.

    X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
            publicKey.getEncoded());
    FileOutputStream fos = new FileOutputStream("public.key");
    fos.write(x509EncodedKeySpec.getEncoded());
    fos.close();

    // Store Private Key.
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
            privateKey.getEncoded());
    fos = new FileOutputStream("private.key");
    fos.write(pkcs8EncodedKeySpec.getEncoded());
    fos.close();

    //Get the public and private keys out of their files
    getPubAndPrivateKey();

    //Check if the keys gotten out of the files are the same as the generated files (this returns truetrue)
    System.out.print(publicKey.equals(pubKey));
    System.out.print(privateKey.equals(privKey));


    byte[] text = "This is my super secret secret".getBytes();
    encryptToFile("encrypted.txt", text );
    decryptToFile("encrypted.txt", "decrypted.txt");

}

从文件中获取密钥

private static void getPubAndPrivateKey() throws IOException, Exception {
    // Read Public Key.
    File filePublicKey = new File("public.key");
    FileInputStream fis = new FileInputStream("public.key");
    byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
    fis.read(encodedPublicKey);
    fis.close();

    // Read Private Key.
    File filePrivateKey = new File("private.key");
    fis = new FileInputStream("private.key");
    byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
    fis.read(encodedPrivateKey);
    fis.close();

    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
            encodedPublicKey);
    pubKey = keyFactory.generatePublic(publicKeySpec);

    PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
            encodedPrivateKey);
    privKey = keyFactory.generatePrivate(privateKeySpec);

}

加密

    public static void encryptToFile(String fileName, byte[] data)
        throws IOException {

    try {
        cip.init(Cipher.ENCRYPT_MODE, privKey);
        byte[] cipherData = cip.doFinal(data);
        String encryptedData = cipherData.toString();
        BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
        out.write(encryptedData);
        out.close();

    } catch (Exception e) {
        throw new RuntimeException("Spurious serialisation error", e);
    }

}

解密

private static void decryptToFile(String string, String string2)
        throws Exception {

    try {
        File encryptedFile = new File("encrypted.txt");

        byte[] encrypted = getContents(encryptedFile).getBytes();

        cip = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cip.init(Cipher.DECRYPT_MODE, pubKey);

        byte[] cipherData = cip.doFinal(encrypted);

        String decryptedData = cipherData.toString();
        BufferedWriter out = new BufferedWriter(new FileWriter(
                "decrypted.txt"));
        out.write(decryptedData);
        out.close();

    } catch (Exception e) {
        throw e;
    }
}

我已检查的内容

  • 解密中使用的数据与加密文件中的数据相同
  • 生成的密钥与从文件中获取的密钥相同
  • 加密和解密都不会出错

结果
原始字符串:
我超级秘密的秘密 加密结果如下:
[B @ 1747b17 解密结果如下: [B @ 91a4fb

2 个答案:

答案 0 :(得分:3)

如果通过toString()方法打印出一个字节数组,则会得到一个完全独立于内容的值。

因此价值[B @ 1747b17 [B @ 91a4fb只是垃圾,不会告诉你任何事情。

如果要打印字节数组的内容,请将其转换为Base64或hex-string。

System.out.println(new sun.misc.BASE64Encoder().encode(myByteArray)); 

可以使用Apache Commons Codec library中的org.apache.commons.codec.binary.Hex生成十六进制字符串。

答案 1 :(得分:1)

我同意上述答案。 我想补充一点,在你的情况下,你可以简单地使用FileOutputStream,将字节写入文件 - 例如:

public static void encryptToFile(String fileName, byte[] data)
        throws IOException {

    FileOutputStream out = null;
    try {
        cip.init(Cipher.ENCRYPT_MODE, privKey);
        byte[] cipherData = cip.doFinal(data);
        out  = new FileOutputStream(fileName);
        out.write(cipherData);
    } catch (Exception e) {
        throw new RuntimeException("Spurious serialisation error", e);
    } finally {
       if (fos != null) {
           try {
              fos.close();
           } catch (IOException ex) {
           }
       }
    }

}