C#如何给一个PDF做MD5验签?

咨询区

  • broke

我用 iTextSharp 操作 PDF ,我的项目需求需要定时的读取PDF来判断其是否被修改,现在我遇到了一个难点,PDF 中都是一些图片,我无法用 iTextSharp 进行提取,所以我想了一个办法就是对 PDF 做一个 MD5 的验签,如果 MD5 改变了,那 PDF 自然就被修改了。.

这只是我的想法,我不知道如何用代码对 PDF 做验签,如果大家能提供一些代码就好了,先谢谢了。

回答区

  • Jon Skeet

这个非常简单,用 System.Security.Cryptography.MD5 就可以啦,参考代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            var path = Environment.CurrentDirectory + "//1.pdf";

            var md5 = GetFileMD5(path);

            Console.ReadLine();
        }

        static byte[] GetFileMD5(string path)
        {
            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(path))
                {
                    return md5.ComputeHash(stream);
                }
            }
        }
    }

然后你就可以比较 byte[] 是否相等来判断PDF是否修改,当然你觉得麻烦的话,也可以将 byte[] 转成 string 进行比较,不过这里就需要使用 BitConverter 类,参考如下代码:

static string CalculateMD5(string filename)
{
    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(filename))
        {
            var hash = md5.ComputeHash(stream);
            return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
        }
    }
}
  • Badaro Jr.

我在项目中是用反射来解决的,参考我的 GetHash 方法。

public static String GetHash<T>(Stream stream) where T : HashAlgorithm {
    StringBuilder sb = new StringBuilder();

    MethodInfo create = typeof(T).GetMethod("Create", new Type[] {});
    using (T crypt = (T) create.Invoke(null, null)) {
        byte[] hashBytes = crypt.ComputeHash(stream);
        foreach (byte bt in hashBytes) {
            sb.Append(bt.ToString("x2"));
        }
    }
    return sb.ToString();
}

然后就可以像下面这样使用。

using (FileStream fStream = File.OpenRead(filename)) {
    return GetHash<MD5>(fStream)
}

可能这不是最好的方法,但对我来说是最合适的。

点评区

可以看到大家基本都是用 ComputeHash() 解决的,学习了。