java - 使用 aes 从 java 解密文件中的额外字符

标签 java encryption aes vb.net-2010

我在 vb.net 中编写了代码来加密内存流中的文件。我还解密文件并将内存流复制到文件中以确保加密/解密工作。我的 vb 解决方案有效。

但是我需要使用 Java 进行解密。当我解密文件时,我总是会得到一个额外的“?”字符位于文件的开头,但除此之外,结果是完美的。以前有人见过这样的事情吗?我必须承认,我的结果仅使用一组数据,但我两次都使用新 key 和 vector 对其进行了两次加密。

一些细节。我在 vb 中使用 AES、PKCS7 填充,在 Java 中使用 PKCS5 填充。该文件可以是任意长度。如有任何帮助,我们将不胜感激。

我是通过手机发布此内容的,但手头没有代码。我明天可以添加。我只是希望这个描述能引起某人的注意。

谢谢, SH

当我在 VB 中写入 MemoryStream 时,我声明了一个 StreamWriter,如下所示:

Writer = New IO.StreamWriter(MS, System.Text.Encoding.UTF8)

这是我的 VB.NET 加密函数。

    Public Shared Function WriteEncryptedFile(ms As MemoryStream, FileName As String) As List(Of Byte())

    Try
        Dim original() As Byte
        Dim myAes As System.Security.Cryptography.Aes = Aes.Create()
        myAes.KeySize = 128
        myAes.Padding = PadMode
        Dim keys As New List(Of Byte())
        keys.Add(myAes.Key)
        keys.Add(myAes.IV)

        original = ms.ToArray
        Dim encryptor As ICryptoTransform = myAes.CreateEncryptor(myAes.Key, myAes.IV)
        Using FileEncrypt As New FileStream(FileName, FileMode.Create, FileAccess.Write)
            Using csEncrypt As New CryptoStream(FileEncrypt, encryptor, CryptoStreamMode.Write)
                csEncrypt.Write(original, 0, original.Length)
                csEncrypt.FlushFinalBlock()
                FileEncrypt.Flush()
                FileEncrypt.Close()
                csEncrypt.Close()
            End Using
        End Using

        Return keys
    Catch e As Exception
        MsgBox("Error during encryption." & vbCrLf & e.Message)
    End Try
    Return Nothing
End Function

这是 Java 解密:

public static void DecryptLIGGGHTSInputFile(String fileIn, String fileOut, String base64Key, String base64IV) throws Exception
{

    // Get the keys from base64 text
    byte[] key = Base64.decodeBase64(base64Key);
    byte[] iv= Base64.decodeBase64(base64IV);

    // Read fileIn into a byte[]
    int len = (int)(new File(fileIn).length());
    byte[] cipherText = new byte[len];
    FileInputStream bs = new FileInputStream(fileIn);
    bs.read(cipherText, 1, len-1);
    System.out.println(cipherText.length);
    System.out.println((double)cipherText.length/128);
    bs.close();

    // Create an Aes object 
    // with the specified key and IV. 
    Cipher cipher = null;
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

    // Encrypt the message. 
    SecretKey secret = new SecretKeySpec(key, "AES");

    /*
    cipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);
    cipherText = cipher.doFinal("Hello, World!".getBytes("UTF-8"));
    System.out.println(cipherText);
    */

    cipher.init(Cipher.DECRYPT_MODE, secret , new IvParameterSpec(iv));
    String plaintext = new String(cipher.doFinal(cipherText), "UTF-8");
    System.out.println(plaintext.length());


    FileWriter fw = new FileWriter(fileOut);
    fw.write(plaintext);
    fw.close();
}

最佳答案

这是一个 BOM 问题。当我用VB创建MemoryStream时,我用UTF-8编码初始化它。文件中的第一个字符将流的大小和位置从 0 字节增加到 4 字节,而它本来应该只有 1 个字节。解决方案是创建基于 UTF-8 且不带字节顺序标记的编码,如下所示:

Dim UTF8EncodingWOBOM As New System.Text.UTF8Encoding(False) 'indicates to omit BOM
Writer = New IO.StreamWriter(MS, UTF8EncodingWOBOM)

我读到here由于字节顺序标记的存在或缺乏,平台之间经常出现编码不兼容的问题,因为它既不推荐也不要求。用一没有对,用一也没有错。基本上你必须找到一种方法来对付它们。许多其他文章和帖子提出了不同的方法。要点是,要么识别它们,如果存在就对其进行处理。由于我可以控制写作和阅读,因此完全取消它们也很有意义。

SH

关于java - 使用 aes 从 java 解密文件中的额外字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17738441/

相关文章:

java - Spring 管理的事务未启动

java - 如何计算给定的BigDecimal值占用的内存?

java - 将 System.out.println 或 stdout 数据捕获到 swing 备忘录(大数据)

ios - aes 128 消息解密——Swift、iOS

java - ImageIO.read() 是否考虑 EXIF 方向元数据?

java - 自编码 RSA 实现

php - c++ 和 php 中的 openssl 加密

php - 密码哈希无法登录 codeigniter

windows - UWP 中用于 Xamarin Forms 项目的 AES 加密

java - Java 中的 ECB 和 CBC AES 输出相同