AES 256加密和解密Java
当我尝试解密已加密的Whit php的OGG文件时,我有问题
。
您好, “ nofollow noreferrer”> php crypt函数
我用java使用了此代码,但生成的文件是损坏的
public static String decrypt(String input, String key){
byte[] bytes = Base64.getDecoder().decode(input);
if(bytes.length < 17) {
return null;
}
String result = null;
//byte[] ivBytes = Arrays.copyOfRange(bytes, 0, 16);
//byte[] contentBytes = Arrays.copyOfRange(bytes, 16, bytes.length);
try {
//Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
Key skey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
// Set the appropriate size for mInitVec by Generating a New One
AlgorithmParameters params = cipher.getParameters();
byte[] mInitVec = params.getParameterSpec(IvParameterSpec.class).getIV();
cipher.init(Cipher.DECRYPT_MODE, skey, new IvParameterSpec(mInitVec));
byte[] decrypted = cipher.doFinal(bytes);
String uploadedFileLocation = "C:\\test3.ogg";
FileOutputStream fs = new FileOutputStream(new File(uploadedFileLocation));
fs.write(decrypted);
fs.close();
result ="decrypted";
} catch (
Exception ex
) {
System.out.println(ex.toString());
}
return result;
}
Hello I have an issue when I trying to decrypt an Ogg file whit java that was encrypted whit PHP
this is the function that creates the encrypted file
I used this code with java but the generated file is corrupt
public static String decrypt(String input, String key){
byte[] bytes = Base64.getDecoder().decode(input);
if(bytes.length < 17) {
return null;
}
String result = null;
//byte[] ivBytes = Arrays.copyOfRange(bytes, 0, 16);
//byte[] contentBytes = Arrays.copyOfRange(bytes, 16, bytes.length);
try {
//Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
Key skey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
// Set the appropriate size for mInitVec by Generating a New One
AlgorithmParameters params = cipher.getParameters();
byte[] mInitVec = params.getParameterSpec(IvParameterSpec.class).getIV();
cipher.init(Cipher.DECRYPT_MODE, skey, new IvParameterSpec(mInitVec));
byte[] decrypted = cipher.doFinal(bytes);
String uploadedFileLocation = "C:\\test3.ogg";
FileOutputStream fs = new FileOutputStream(new File(uploadedFileLocation));
fs.write(decrypted);
fs.close();
result ="decrypted";
} catch (
Exception ex
) {
System.out.println(ex.toString());
}
return result;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
TLDR:使用IV(初始化向量或有时Nonce)解密,主要是IV
,例如CBC(例如CBC),必须像加密一样使用相同的IV(和键) 。此外,像CBC这样的块模式通常需要填充和取消数据,而PHP使用的OPENSL确实使用Java也支持但必须选择的“标准” PKCS5/7填充。
对于真实的应用程序,您当然不会使用硬编码数据(通常也不应该硬编码密钥),并且将PHP应用程序生成的数据传递给Java应用程序的数据的方法有所不同(很多!)。一种非uncommon的方法是将iv和ciphertext(最好也是Mac或auth标签)连接用于传输和/或存储,然后用两个
arrays.copyofrange
与代码分开在评论中,但是对于此演示,我只是base64-ed每件(openssl_encrypt已经完成了base64 base64)。请注意,对于AES-256,密钥必须正好是32个字节(并且应该是任意字节,而不是人类可以识别的字符)。在php/openssl中,如果您提供的量低于要求的静音板,则具有零字节(又称nul),但java却没有。如果您在Java中的
byte []
过于简短,则可以方便地使用egarrays.copyof(poorkey,32)
将其方便地零。TLDR: it's mostly the IV
For encryption modes like CBC that use an IV (initialization vector, or sometimes nonce) decryption must use the same IV (and key) as encryption did. In addition, a block mode like CBC generally requires padding and unpadding the data, and OpenSSL as used by PHP does so using the 'standard' PKCS5/7 padding which Java also supports but must select.
For a real application of course you wouldn't use hardcoded data (and usually shouldn't hardcode key either) and the method of passing the data produced by the PHP app to the Java app varies (a lot!). One not-uncommon way is to concatenate the IV and ciphertext (and preferably a MAC or auth tag as well) for transmission and/or storage and then separate them with code like the two
Arrays.copyOfRange
you have in comments, but for this demo I simply base64-ed each piece (openssl_encrypt already does base64 by default).Note for AES-256 the key must be exactly 32 bytes (and should be arbitrary bytes, not characters recognizable to a human). In PHP/OpenSSL if you provide less than required it silently pads with zero bytes (aka NUL), but Java does not; if you have a too-short
byte[]
in Java you can conveniently zero-pad it with e.g.Arrays.copyOf(poorkey,32)
.