在java中解密文件哈希验证失败

在java中解密文件哈希验证失败,java,aes,encryption,Java,Aes,Encryption,我使用的这个示例来自代码项目-C#encryption的java实现 解密时,文件会被解密,但使用旧哈希验证当前哈希时,旧哈希的最后几个字节为零,验证失败 我的解密java实现如下: private void mDecrypt_File(FileInputStream fin, String outFile) throws Exception { FileOutputStream fout = new FileOutputStream(outFile); byte[] iv

我使用的这个示例来自代码项目-C#encryption的java实现

解密时,文件会被解密,但使用旧哈希验证当前哈希时,旧哈希的最后几个字节为零,验证失败

我的解密java实现如下:

 private void mDecrypt_File(FileInputStream fin, String outFile) throws Exception {
    FileOutputStream fout = new FileOutputStream(outFile);

    byte[] iv = new byte[16];
    byte[] salt = new byte[16];
    byte[] len = new byte[8];
    byte[] FC_TAGBuffer = new byte[8];

    Cipher cipher = Cipher.getInstance(CIPHER_INSTANCE);

    DataInputStream dis = new DataInputStream(fin);

    dis.read(iv, 0, 16);
    dis.read(salt, 0, 16);

    Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(DEFAULT_PASSWORD, salt, F_ITERATIONS);
    SecretKey key = new SecretKeySpec(rfc.getBytes(32), "AES");

    //decryption code
    cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
    CipherInputStream cIn = new CipherInputStream(dis, cipher);

    cIn.read(len, 0, 8);
    long lSize = getLong(len, 0);

    cIn.read(FC_TAGBuffer, 0, 8);

    byte[] tempFC_TAGBuffer = changeByteArray(FC_TAGBuffer, 0);//new byte[8];                           

    BigInteger ulong = new BigInteger(1, tempFC_TAGBuffer);

    if (!ulong.equals(FC_TAG)) {
        Exception ex = new Exception("Tags are not equal");
        throw ex;
    }

    byte[] bytes = new byte[BUFFER_SIZE];
    //determine number of reads to process on the file                          
    long numReads = lSize / BUFFER_SIZE;
    // determine what is left of the file, after numReads                   
    long slack = (long) lSize % BUFFER_SIZE;

    int read = -1;
    int value = 0;
    int outValue = 0;

    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.reset();
    // read the buffer_sized chunks         
    for (int i = 0; i < numReads; ++i) {
        read = cIn.read(bytes, 0, bytes.length);
        fout.write(bytes, 0, read);
        md.update(bytes, 0, read);
        value += read;
        outValue += read;
    }
    // now read the slack                   
    if (slack > 0) {
        read = cIn.read(bytes, 0, (int) slack);
        fout.write(bytes, 0, read);
        md.update(bytes, 0, read);
        value += read;
        outValue += read;
    }
    fout.flush();
    fout.close();
    byte[] curHash = md.digest();

    byte[] oldHash = new byte[md.getDigestLength()];
    read = cIn.read(oldHash, 0, oldHash.length);
    if (oldHash.length != read || (!CheckByteArrays(oldHash, curHash))) {
        Exception ex = new Exception("File Corrupted!");
        throw ex;
    }
    if (outValue != lSize) {
        Exception ex = new Exception("File Sizes don't match!");
        throw ex;
    }
}
private void mDecrypt_文件(FileInputStream fin,String outFile)引发异常{
FileOutputStream fout=新的FileOutputStream(输出文件);
字节[]iv=新字节[16];
字节[]salt=新字节[16];
字节[]len=新字节[8];
字节[]FC_TAGBuffer=新字节[8];
Cipher Cipher=Cipher.getInstance(Cipher\u实例);
DataInputStream dis=新的DataInputStream(fin);
dis.read(iv,0,16);
dis.read(salt,0,16);
Rfc2898DeriveBytes rfc=新的Rfc2898DeriveBytes(默认密码、salt、F_迭代);
SecretKey=newsecretkeyspec(rfc.getBytes(32),“AES”);
//解密码
cipher.init(cipher.DECRYPT_模式,密钥,新的IvParameterSpec(iv));
CipherInputStream cIn=新的CipherInputStream(dis,cipher);
cIn.read(len,0,8);
long lSize=getLong(len,0);
cIn.read(FC_TAGBuffer,0,8);
字节[]tempFC_TAGBuffer=changeByteArray(FC_TAGBuffer,0);//新字节[8];
BigInteger ulong=新的BigInteger(1,tempFC_TAGBuffer);
如果(!ulong.equals(FC_标记)){
异常ex=新异常(“标记不相等”);
掷骰子;
}
字节[]字节=新字节[缓冲区大小];
//确定文件上要处理的读取数
长numReads=lSize/缓冲区大小;
//在numReads之后确定文件的剩余部分
长松弛=(长)lSize%缓冲区大小;
int read=-1;
int值=0;
int-outValue=0;
MessageDigest md=MessageDigest.getInstance(“SHA-256”);
md.reset();
//读取缓冲区大小的块
对于(int i=0;i0){
read=cIn.read(字节,0,(int)slack);
四次写入(字节,0,读取);
md.update(字节,0,读取);
值+=读取;
输出值+=读取;
}
fout.flush();
fout.close();
字节[]curHash=md.digest();
byte[]oldHash=新字节[md.getDigestLength()];
read=cIn.read(oldHash,0,oldHash.length);
if(oldHash.length!=read | |(!CheckByteArrays(oldHash,curHash))){
异常ex=新异常(“文件损坏!”);
掷骰子;
}
if(outValue!=lSize){
Exception ex=新异常(“文件大小不匹配!”);
掷骰子;
}
}
这种解密方法在android上有效,但在简单的java项目中不起作用。 正在从Java/Android或.NET对文件进行加密


谢谢。

有什么错误/异常?read=cIn.read(oldHash,0,oldHash.length);此行从cIn读取的剩余字节不等于当前哈希。因此,检查(oldHash.length!=read | |(!checkbytearray(oldHash,curHash)))是否失败。假设我们有5个字节的数据,解密后,旧散列(应该是32字节长)将是27字节长,旧散列中的重命名字节是零。所以,你不能读取足够的字节?跟踪你的代码,检查你的输入数据。如果你不知道,我可以重复我自己的话:获取Java和Android的saem代码和输入,并排调试它们,比较出了什么问题。我在.NET和Java上并排调试,哈希字节的值不同,但.NET获取的oldhash和currhash完全相同,但在JAVA中,最后几个字节为零(零正好等于数据的长度)。如果你想试试,我也可以发布加密方法。