Skip to content
This repository was archived by the owner on Sep 30, 2022. It is now read-only.

Commit 175c86c

Browse files
committed
Made it use BouncyCastle to do MD5 digests when in the browser
1 parent c161720 commit 175c86c

File tree

4 files changed

+43
-55
lines changed

4 files changed

+43
-55
lines changed

src/iTextSharp.LGPLv2.Core/MD5.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Org.BouncyCastle.Crypto.Digests;
2+
using System;
3+
using System.Runtime.CompilerServices;
4+
using System.Security.Cryptography;
5+
6+
namespace iTextSharp
7+
{
8+
/// <summary>
9+
/// RFC1321: The MD5 Message-Digest Algorithm
10+
/// https://datatracker.ietf.org/doc/html/rfc1321
11+
/// </summary>
12+
public sealed class MD5BouncyCastle : HashAlgorithm
13+
{
14+
public static new HashAlgorithm Create() =>
15+
System.Runtime.InteropServices.RuntimeInformation.OSDescription == "Browser" ? new MD5BouncyCastle() : MD5.Create();
16+
private MD5BouncyCastle() { }
17+
18+
private MD5Digest _digestInternal = new();
19+
20+
public override void Initialize() {}
21+
22+
protected override void HashCore(byte[] array, int ibStart, int cbSize)
23+
{
24+
_digestInternal.BlockUpdate(array, ibStart, cbSize);
25+
}
26+
27+
protected override byte[] HashFinal()
28+
{
29+
byte[] output = new byte[_digestInternal.GetByteLength()];
30+
_digestInternal.DoFinal(output, 0);
31+
return output;
32+
}
33+
}
34+
}

src/iTextSharp.LGPLv2.Core/iTextSharp/text/ImgJBIG2.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public ImgJbig2(int width, int height, byte[] data, byte[] globals) : base((Uri)
5252
_global = globals;
5353
try
5454
{
55-
using (var md5 = MD5.Create())
55+
using (var md5 = MD5BouncyCastle.Create())
5656
{
5757
_globalHash = md5.ComputeHash(_global);
5858
}

src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfEncryption.cs

Lines changed: 7 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public static byte[] CreateDocumentId()
116116
long time = DateTime.Now.Ticks + Environment.TickCount;
117117
long mem = GC.GetTotalMemory(false);
118118
string s = time + "+" + mem + "+" + (Seq++);
119-
return MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(s));
119+
return MD5BouncyCastle.Create().ComputeHash(Encoding.ASCII.GetBytes(s));
120120
}
121121

122122
public static PdfObject CreateInfoId(byte[] id)
@@ -396,8 +396,7 @@ public void SetCryptoMode(int mode, int kl)
396396

397397
public void SetHashKey(int number, int generation)
398398
{
399-
#if NET40
400-
using (var md5 = new MD5CryptoServiceProvider())
399+
using (var md5 = MD5BouncyCastle.Create())
401400
{
402401
md5.Initialize();
403402
Extra[0] = (byte)number;
@@ -415,22 +414,6 @@ public void SetHashKey(int number, int generation)
415414
md5.TransformFinalBlock(Extra, 0, 0);
416415
Key = md5.Hash;
417416
}
418-
#else
419-
using (var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5))
420-
{
421-
Extra[0] = (byte)number;
422-
Extra[1] = (byte)(number >> 8);
423-
Extra[2] = (byte)(number >> 16);
424-
Extra[3] = (byte)generation;
425-
Extra[4] = (byte)(generation >> 8);
426-
md5.AppendData(Mkey, 0, Mkey.Length);
427-
md5.AppendData(Extra, 0, Extra.Length);
428-
if (_revision == AES_128)
429-
md5.AppendData(_salt, 0, _salt.Length);
430-
431-
Key = md5.GetHashAndReset();
432-
}
433-
#endif
434417

435418
KeySize = Mkey.Length + 5;
436419
if (KeySize > 16)
@@ -443,7 +426,7 @@ public void SetHashKey(int number, int generation)
443426
public void SetupAllKeys(byte[] userPassword, byte[] ownerPassword, int permissions)
444427
{
445428
if (ownerPassword == null || ownerPassword.Length == 0)
446-
ownerPassword = MD5.Create().ComputeHash(CreateDocumentId());
429+
ownerPassword = MD5BouncyCastle.Create().ComputeHash(CreateDocumentId());
447430

448431
permissions |= (int)((_revision == STANDARD_ENCRYPTION_128 || _revision == AES_128) ? 0xfffff0c0 : 0xffffffc0);
449432
permissions &= unchecked((int)0xfffffffc);
@@ -480,7 +463,7 @@ public void SetupByUserPassword(byte[] documentId, byte[] userPassword, byte[] o
480463
private byte[] computeOwnerKey(byte[] userPad, byte[] ownerPad)
481464
{
482465
byte[] ownerKey = new byte[32];
483-
var md5 = MD5.Create();
466+
var md5 = MD5BouncyCastle.Create();
484467
byte[] digest = md5.ComputeHash(ownerPad);
485468
if (_revision == STANDARD_ENCRYPTION_128 || _revision == AES_128)
486469
{
@@ -549,9 +532,8 @@ private void setupGlobalEncryptionKey(byte[] documentId, byte[] userPad, byte[]
549532
Mkey = new byte[_keyLength / 8];
550533
byte[] digest = new byte[Mkey.Length];
551534

552-
#if NET40
553535
//fixed by ujihara in order to follow PDF refrence
554-
using (var md5 = new MD5CryptoServiceProvider())
536+
using (var md5 = MD5BouncyCastle.Create())
555537
{
556538
md5.Initialize();
557539
md5.TransformBlock(userPad, 0, userPad.Length, userPad, 0);
@@ -571,33 +553,14 @@ private void setupGlobalEncryptionKey(byte[] documentId, byte[] userPad, byte[]
571553

572554
Array.Copy(md5.Hash, 0, digest, 0, Mkey.Length);
573555
}
574-
#else
575-
//fixed by ujihara in order to follow PDF refrence
576-
var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5);
577-
md5.AppendData(userPad, 0, userPad.Length);
578-
md5.AppendData(ownerKey, 0, ownerKey.Length);
579-
580-
byte[] ext = new byte[4];
581-
ext[0] = (byte)permissions;
582-
ext[1] = (byte)(permissions >> 8);
583-
ext[2] = (byte)(permissions >> 16);
584-
ext[3] = (byte)(permissions >> 24);
585-
md5.AppendData(ext, 0, 4);
586-
if (documentId != null)
587-
md5.AppendData(documentId, 0, documentId.Length);
588-
if (!_encryptMetadata)
589-
md5.AppendData(MetadataPad, 0, MetadataPad.Length);
590-
591-
Array.Copy(md5.GetHashAndReset(), 0, digest, 0, Mkey.Length);
592-
#endif
593556

594557

595558
// only use the really needed bits as input for the hash
596559
if (_revision == STANDARD_ENCRYPTION_128 || _revision == AES_128)
597560
{
598561
for (int k = 0; k < 50; ++k)
599562
{
600-
using (var md5Hash = MD5.Create())
563+
using (var md5Hash = MD5BouncyCastle.Create())
601564
{
602565
Array.Copy(md5Hash.ComputeHash(digest), 0, digest, 0, Mkey.Length);
603566
}
@@ -617,22 +580,13 @@ private void setupUserKey()
617580
if (_revision == STANDARD_ENCRYPTION_128 || _revision == AES_128)
618581
{
619582
byte[] digest;
620-
#if NET40
621-
using (var md5 = new MD5CryptoServiceProvider())
583+
using (var md5 = MD5BouncyCastle.Create())
622584
{
623585
md5.Initialize();
624586
md5.TransformBlock(_pad, 0, _pad.Length, _pad, 0);
625587
md5.TransformFinalBlock(DocumentId, 0, DocumentId.Length);
626588
digest = md5.Hash;
627589
}
628-
#else
629-
using (var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5))
630-
{
631-
md5.AppendData(_pad, 0, _pad.Length);
632-
md5.AppendData(DocumentId, 0, DocumentId.Length);
633-
digest = md5.GetHashAndReset();
634-
}
635-
#endif
636590
Array.Copy(digest, 0, UserKey, 0, 16);
637591
for (int k = 16; k < 32; ++k)
638592
UserKey[k] = 0;

src/iTextSharp.LGPLv2.Core/iTextSharp/text/pdf/PdfSmartCopy.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ private void serObject(PdfObject obj, int level, ByteBuffer bb)
176176
serDic((PdfDictionary)obj, level - 1, bb);
177177
if (level > 0)
178178
{
179-
using (var md5 = MD5.Create())
179+
using (var md5 = MD5BouncyCastle.Create())
180180
{
181181
bb.Append(md5.ComputeHash(PdfReader.GetStreamBytesRaw((PrStream)obj)));
182182
}

0 commit comments

Comments
 (0)