crypto-js - 读取和解密文件

时间:2014-12-09 09:51:57

标签: javascript encryption cryptojs

我有一些用于执行AES加密的Java函数,一个用于字符串,一个用于文件

private static final String AES_CIPHER_METHOD = "AES";

public static SecretKeySpec createAesKeySpec(byte[] aesKey) {
    return new SecretKeySpec(aesKey, AES_CIPHER_METHOD);
}

public static String aesEncrypt(String data, SecretKeySpec aesKeySpec) throws EncryptionException {
    try {
        Cipher aesCipher = Cipher.getInstance(AES_CIPHER_METHOD);
        aesCipher.init(Cipher.ENCRYPT_MODE, aesKeySpec);
        byte[] encVal = aesCipher.doFinal(data.getBytes("UTF8"));
        return new BASE64Encoder().encode(encVal);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IOException | BadPaddingException| IllegalBlockSizeException e) {
        throw new EncryptionException(e.getMessage(), e);
    }
}

public static void aesEncryptFile(File in, File out, SecretKeySpec aesKeySpec) throws EncryptionException {
    try {
        Cipher aesCipher = Cipher.getInstance(AES_CIPHER_METHOD);
        aesCipher.init(Cipher.ENCRYPT_MODE, aesKeySpec);

        try (InputStream inputStream = new FileInputStream(in)) {
            try (OutputStream outputStream = new CipherOutputStream(new FileOutputStream(out), aesCipher)){
                IOUtils.copy(inputStream, outputStream);
            }
        }
    } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IOException e){
        throw new EncryptionException(e.getMessage(), e);
    }
}

我也有一些测试来输出一些测试数据

private static final String KEY_STRING = "DpiA4l0gvb7biWZtiN6Vjg==";

private SecretKeySpec createKeySpec() {
    byte[] keyBytes = new Base64().decode(KEY_STRING.getBytes());
    return EncryptionUtils.createAesKeySpec(keyBytes);
}

public void testAesEncryptString() throws EncryptionException {
    String encryptedData = EncryptionUtils.aesEncrypt("A normal string", createKeySpec());
    System.out.println(encryptedData); //outputs 3XLwlSHWLm98teIoIS6QTA==
}

public void testAesEncryptStringFile() throws EncryptionException, IOException {
    File newFile = new File(FilenameUtils.concat(System.getProperty("java.io.tmpdir"), "myFile.txt"));
    FileUtils.writeStringToFile(newFile, "A string in a file");

    File encryptedFile = new File(FilenameUtils.concat(System.getProperty("java.io.tmpdir"), "myFile_encrypted.txt"));

    EncryptionUtils.aesEncryptFile(newFile, encryptedFile, createKeySpec());
}

我现在需要在javascript中实现解密。

我已成功使用crypto-js成功解密普通字符串,但是,我只是无法让文件部分正常工作,而且我看不出有什么问题

var base64Key = "DpiA4l0gvb7biWZtiN6Vjg==";
var key = CryptoJS.enc.Base64.parse(base64Key);

var aesOptions = {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
};

var decryptedData = CryptoJS.AES.decrypt( "3XLwlSHWLm98teIoIS6QTA==", key, aesOptions);
var decryptedText = decryptedData.toString( CryptoJS.enc.Utf8 );
console.log( "decryptedText = " + decryptedText ); //CORRECT outputs "A normal string"

var encryptedFilename = "https://dl.dropboxusercontent.com/u/30823828/myFile_encrypted.txt";
$.get(encryptedFilename, function(data){
    console.log("encrypted file content", data);
    var encryptedData = CryptoJS.enc.Base64.parse(data);
    var decryptedData = CryptoJS.AES.decrypt( encryptedData, key, aesOptions);
    var decryptedText = decryptedData.toString( CryptoJS.enc.Utf8 );
    console.log( "decrypted file content = " + decryptedText ); //INCORRECT outputs "" SHOULD output "A string in a file"
});

链接到jsfiddle - http://jsfiddle.net/pKNzV/46/

1 个答案:

答案 0 :(得分:1)

经过大量的反复试验后,我能够实现这一目标。

函数base64ArrayBuffer来自以下 - https://gist.github.com/jonleighton/958841

var base64Key = "DpiA4l0gvb7biWZtiN6Vjg==";
var key = CryptoJS.enc.Base64.parse(base64Key);

var aesOptions = {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
};

var encryptedFilename = "https://dl.dropboxusercontent.com/u/30823828/myFile_encrypted.txt";

var oReq = new XMLHttpRequest();
oReq.open("GET", encryptedFilename, true);
oReq.responseType = "arraybuffer";

oReq.onload = function (oEvent) {
   var data = oReq.response;
   if (data) {
      encodedData = base64ArrayBuffer(data);
      var decryptedData = CryptoJS.AES.decrypt( encodedData, key, aesOptions);
      var decryptedText = decryptedData.toString( CryptoJS.enc.Utf8 );
      console.log( "decryptedText = " + decryptedText );
      console.log("file decrypt successful: ", "A string in a file" === decryptedText);
   }
};

oReq.send(null);