Aes使用base64数据编码解密java文件
我提到并尝试使用base64解码进行文件解密 我的要求是在加密期间使用base64编码数据,在解密期间使用base64解码数据 但我面临以下错误:Aes使用base64数据编码解密java文件,java,encryption,openssl,base64,sha1,Java,Encryption,Openssl,Base64,Sha1,我提到并尝试使用base64解码进行文件解密 我的要求是在加密期间使用base64编码数据,在解密期间使用base64解码数据 但我面临以下错误: javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher at java.base/com.sun.crypto.provider.CipherCore.doFinal(Unkno
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at java.base/com.sun.crypto.provider.CipherCore.doFinal(Unknown Source)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(Unknown Source)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(Unknown Source)
at java.base/javax.crypto.Cipher.doFinal(Unknown Source)
at aes.DecryptNew.decryptNew(DecryptNew.java:124)
at aes.DecryptNew.main(DecryptNew.java:32)
另外,我对如何在块中执行解密感到困惑。
请向我建议此代码中的问题
import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.util.Arrays;
import java.util.Base64;
public class DecryptNew {
public static void main(String[] args) {
String plaintextFilename = "D:\\\\plaintext.txt";
String ciphertextFilename = "D:\\\\plaintext.txt.crypt";
String decryptedtextFilename = "D:\\\\plaintextDecrypted.txt";
String password = "testpass";
writeToFile();
String ciphertext = encryptfile(plaintextFilename, password);
System.out.println("ciphertext: " + ciphertext);
decryptNew(ciphertextFilename, password, decryptedtextFilename);
}
static void writeToFile() {
BufferedWriter writer = null;
try
{
writer = new BufferedWriter( new FileWriter("D:\\\\plaintext.txt"));
byte[] data = Base64.getEncoder().encode("hello\r\nhello".getBytes(StandardCharsets.UTF_8));
writer.write(new String(data));
}
catch ( IOException e)
{
}
finally
{
try
{
if ( writer != null)
writer.close( );
}
catch ( IOException e)
{
}
}
}
public static String encryptfile(String path, String password) {
try {
FileInputStream fis = new FileInputStream(path);
FileOutputStream fos = new FileOutputStream(path.concat(".crypt"));
final byte[] pass = Base64.getEncoder().encode(password.getBytes());
final byte[] salt = (new SecureRandom()).generateSeed(8);
fos.write(Base64.getEncoder().encode("Salted__".getBytes()));
fos.write(salt);
final byte[] passAndSalt = concatenateByteArrays(pass, salt);
byte[] hash = new byte[0];
byte[] keyAndIv = new byte[0];
for (int i = 0; i < 3 && keyAndIv.length < 48; i++) {
final byte[] hashData = concatenateByteArrays(hash, passAndSalt);
final MessageDigest md = MessageDigest.getInstance("SHA-1");
hash = md.digest(hashData);
keyAndIv = concatenateByteArrays(keyAndIv, hash);
}
final byte[] keyValue = Arrays.copyOfRange(keyAndIv, 0, 32);
final byte[] iv = Arrays.copyOfRange(keyAndIv, 32, 48);
final SecretKeySpec key = new SecretKeySpec(keyValue, "AES");
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
int b;
byte[] d = new byte[8];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
cos.flush();
cos.close();
fis.close();
System.out.println("encrypt done " + path);
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return path;
}
static void decryptNew(String path,String password, String outPath) {
byte[] SALTED_MAGIC = Base64.getEncoder().encode("Salted__".getBytes());
try{
FileInputStream fis = new FileInputStream(path);
FileOutputStream fos = new FileOutputStream(outPath);
final byte[] pass = password.getBytes(StandardCharsets.US_ASCII);
final byte[] inBytes = Files.readAllBytes(Paths.get(path));
final byte[] shouldBeMagic = Arrays.copyOfRange(inBytes, 0, SALTED_MAGIC.length);
if (!Arrays.equals(shouldBeMagic, SALTED_MAGIC)) {
throw new IllegalArgumentException("Initial bytes from input do not match OpenSSL SALTED_MAGIC salt value.");
}
final byte[] salt = Arrays.copyOfRange(inBytes, SALTED_MAGIC.length, SALTED_MAGIC.length + 8);
final byte[] passAndSalt = concatenateByteArrays(pass, salt);
byte[] hash = new byte[0];
byte[] keyAndIv = new byte[0];
for (int i = 0; i < 3 && keyAndIv.length < 48; i++) {
final byte[] hashData = concatenateByteArrays(hash, passAndSalt);
MessageDigest md = null;
md = MessageDigest.getInstance("SHA-1");
hash = md.digest(hashData);
keyAndIv = concatenateByteArrays(keyAndIv, hash);
}
final byte[] keyValue = Arrays.copyOfRange(keyAndIv, 0, 32);
final SecretKeySpec key = new SecretKeySpec(keyValue, "AES");
final byte[] iv = Arrays.copyOfRange(keyAndIv, 32, 48);
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
final byte[] clear = cipher.doFinal(inBytes, 16, inBytes.length - 16);
String contentDecoded = new String(Base64.getDecoder().decode(clear));
fos.write(contentDecoded.getBytes());
fos.close();
System.out.println("Decrypt is completed");
}catch(Exception e){
e.printStackTrace();
}
}
public static byte[] concatenateByteArrays(byte[] a, byte[] b) {
return ByteBuffer
.allocate(a.length + b.length)
.put(a).put(b)
.array();
}
}
导入javax.crypto.Cipher;
导入javax.crypto.CipherOutputStream;
导入javax.crypto.NoSuchPaddingException;
导入javax.crypto.spec.IvParameterSpec;
导入javax.crypto.spec.SecretKeySpec;
导入java.io.BufferedWriter;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.FileWriter;
导入java.io.IOException;
导入java.nio.ByteBuffer;
导入java.nio.charset.StandardCharset;
导入java.nio.file.Files;
导入java.nio.file.path;
导入java.security.*;
导入java.util.array;
导入java.util.Base64;
公共类解密新{
公共静态void main(字符串[]args){
String plaintextFilename=“D:\\\\plaintext.txt”;
字符串ciphertextFilename=“D:\\\\plaintext.txt.crypt”;
String decryptedtextFilename=“D:\\\\plaintextDecrypted.txt”;
字符串password=“testpass”;
writeToFile();
字符串密文=加密文件(明文文件名,密码);
System.out.println(“密文:+ciphertext”);
decryptNew(ciphertextFilename、密码、decryptedtextFilename);
}
静态void writeToFile(){
BufferedWriter=null;
尝试
{
writer=new BufferedWriter(新文件编写器(“D:\\\\plaintext.txt”);
byte[]data=Base64.getEncoder().encode(“hello\r\nhello.getBytes(StandardCharsets.UTF_8));
write(新字符串(数据));
}
捕获(IOE异常)
{
}
最后
{
尝试
{
if(writer!=null)
writer.close();
}
捕获(IOE异常)
{
}
}
}
公共静态字符串加密文件(字符串路径、字符串密码){
试一试{
FileInputStream fis=新的FileInputStream(路径);
FileOutputStream fos=新的FileOutputStream(path.concat(“.crypt”);
最终字节[]pass=Base64.getEncoder().encode(password.getBytes());
最后一个字节[]salt=(new SecureRandom()).generateSeed(8);
fos.write(Base64.getEncoder().encode(“Salted__u;”.getBytes());
写作(salt);
最后一个字节[]passAndSalt=串联字节数组(pass,salt);
字节[]哈希=新字节[0];
字节[]keyAndIv=新字节[0];
对于(int i=0;i<3&&keyAndIv.length<48;i++){
最后一个字节[]hashData=concatenateByteArray(散列,passAndSalt);
final MessageDigest md=MessageDigest.getInstance(“SHA-1”);
hash=md.digest(hashData);
keyAndIv=串联字节数组(keyAndIv,散列);
}
最后一个字节[]keyValue=Arrays.copyOfRange(keyAndIv,0,32);
最后一个字节[]iv=Arrays.copyOfRange(keyAndIv,32,48);
最终SecretKeySpec密钥=新SecretKeySpec(keyValue,“AES”);
final Cipher=Cipher.getInstance(“AES/CBC/PKCS5Padding”);
cipher.init(cipher.ENCRYPT_模式,密钥,新的IvParameterSpec(iv));
CipherOutputStream cos=新的CipherOutputStream(fos,密码);
int b;
字节[]d=新字节[8];
而((b=fis.read(d))!=-1){
cos.write(d,0,b);
}
cos.flush();
cos.close();
fis.close();
System.out.println(“加密完成”+路径);
}捕获(IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e){
e、 printStackTrace();
}
返回路径;
}
静态void decryptNew(字符串路径、字符串密码、字符串输出路径){
字节[]SALTED_umagic=Base64.getEncoder().encode(“SALTED_uuu.getBytes());
试一试{
FileInputStream fis=新的FileInputStream(路径);
FileOutputStream fos=新的FileOutputStream(输出路径);
final byte[]pass=password.getBytes(StandardCharsets.US\u ASCII);
final byte[]inBytes=Files.readAllBytes(path.get(path));
最后一个字节[]应该是MAGIC=Arrays.copyOfRange(以字节为单位,0,SALTED_MAGIC.length);
if(!Arrays.equals(shouldBeMagic,salt_MAGIC)){
抛出新的IllegalArgumentException(“输入的初始字节与OpenSSL SALTED_MAGIC salt值不匹配”);
}
最后一个字节[]salt=Arrays.copyOfRange(以字节为单位,SALTED_MAGIC.length,SALTED_MAGIC.length+8);
最后一个字节[]passAndSalt=串联字节数组(pass,salt);
字节[]哈希=新字节[0];
字节[]keyAndIv=新字节[0];
对于(int i=0;i<3&&keyAndIv.length<48;i++){
最后一个字节[]hashData=concatenateByteArray(散列,passAndSalt);
MessageDigest md=null;
md=MessageDigest.getInstance(“SHA-1”);
hash=md.digest(hashData);
keyAndIv=串联字节数组(keyAndIv,散列);
}
最后一个字节[]keyValue=Arrays.copyOfRange(keyAndIv,0,32);
最终SecretKeySpec密钥=新SecretKeySpec(keyValue,“AES”);
最后一个字节[]iv=Arrays.copyOfRange(keyAndIv,32,48);
final Cipher=Cipher.getInstance(“AES/CBC/PKCS5Padding”);
cipher.init(cipher.DECRYPT_模式,密钥,新的IvParameterSpec(iv));
final byte[]clear=cipher.doFinal(以字节为单位,16,以字节为单位,长度为-16);
String contentDecoded=新字符串(Base64.getDecoder().decode(clear));
fos.write(contentDecoded.getBytes());
fos.close();
System.out.pri
...
byte[] pass = password.getBytes(StandardCharsets.US_ASCII);
byte[] SALTED_MAGIC = "Salted__".getBytes(StandardCharsets.US_ASCII);
byte[] salt = (new SecureRandom()).generateSeed(8);
fos.write(SALTED_MAGIC);
fos.write(salt);
...
...
byte[] pass = password.getBytes(StandardCharsets.US_ASCII);
byte[] SALTED_MAGIC = "Salted__".getBytes(StandardCharsets.US_ASCII);
byte[] prefix = fis.readNBytes(8);
byte[] salt = fis.readNBytes(8);
...
openssl enc -aes-256-cbc -base64 -pass pass:testpass -p -in sample.txt -out sample.crypt
static void decrypt(String path, String password, String outPath) {
try (FileInputStream fis = new FileInputStream(path);
Base64InputStream bis = new Base64InputStream(fis, false, 64, "\r\n".getBytes(StandardCharsets.US_ASCII))) { // from Apache Commons Codec
// Read prefix and salt
byte[] SALTED_MAGIC = "Salted__".getBytes(StandardCharsets.US_ASCII);
byte[] prefix = bis.readNBytes(8);
if (!Arrays.equals(prefix, SALTED_MAGIC)) {
throw new IllegalArgumentException("Initial bytes from input do not match OpenSSL SALTED_MAGIC salt value.");
}
byte[] salt = bis.readNBytes(8);
// Derive key and IV
byte[] pass = password.getBytes(StandardCharsets.US_ASCII);
byte[] passAndSalt = concatenateByteArrays(pass, salt);
byte[] hash = new byte[0];
byte[] keyAndIv = new byte[0];
for (int i = 0; i < 3 && keyAndIv.length < 48; i++) {
byte[] hashData = concatenateByteArrays(hash, passAndSalt);
MessageDigest md = null;
md = MessageDigest.getInstance("SHA-1"); // Use digest from encryption
hash = md.digest(hashData);
keyAndIv = concatenateByteArrays(keyAndIv, hash);
}
byte[] keyValue = Arrays.copyOfRange(keyAndIv, 0, 32);
SecretKeySpec key = new SecretKeySpec(keyValue, "AES");
byte[] iv = Arrays.copyOfRange(keyAndIv, 32, 48);
// Decrypt
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
try (CipherInputStream cis = new CipherInputStream(bis, cipher);
FileOutputStream fos = new FileOutputStream(outPath)) {
int length;
byte[] buffer = new byte[1024];
while ((length = cis.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
}
System.out.println("Decrypt is completed");
} catch (Exception e) {
e.printStackTrace();
}
}
static void decryptfile(String path, String password, String outPath) {
try (FileInputStream fis = new FileInputStream(path)) {
// Read prefix and salt
byte[] SALTED_MAGIC = Base64.getEncoder().encode("Salted__".getBytes());
byte[] prefix = new byte[SALTED_MAGIC.length];
fis.readNBytes(prefix, 0, prefix.length);
if (!Arrays.equals(prefix, SALTED_MAGIC)) {
throw new IllegalArgumentException("Initial bytes from input do not match OpenSSL SALTED_MAGIC salt value.");
}
byte[] salt = new byte[8];
fis.readNBytes(salt, 0, salt.length);
// Derive key and IV
final byte[] pass = Base64.getEncoder().encode(password.getBytes());
byte[] passAndSalt = concatenateByteArrays(pass, salt);
byte[] hash = new byte[0];
byte[] keyAndIv = new byte[0];
for (int i = 0; i < 3 && keyAndIv.length < 48; i++) {
byte[] hashData = concatenateByteArrays(hash, passAndSalt);
MessageDigest md = null;
md = MessageDigest.getInstance("SHA-1"); // Use digest from encryption
hash = md.digest(hashData);
keyAndIv = concatenateByteArrays(keyAndIv, hash);
}
byte[] keyValue = Arrays.copyOfRange(keyAndIv, 0, 32);
SecretKeySpec key = new SecretKeySpec(keyValue, "AES");
byte[] iv = Arrays.copyOfRange(keyAndIv, 32, 48);
// Decrypt
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
try (CipherInputStream cis = new CipherInputStream(fis, cipher);
Base64InputStream bis = new Base64InputStream(cis, false, -1, null); // from Apache Commons Codec
FileOutputStream fos = new FileOutputStream(outPath)) {
int length;
byte[] buffer = new byte[1024];
while ((length = bis.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
}
System.out.println("Decrypt is completed");
} catch (Exception e) {
e.printStackTrace();
}
}