ReportLab fails with ValueError on FIPS enabled systems
Martin Renters via reportlab-users <[email protected]> Sun, 29 Jun 2025 20:13:59 -0400
| Newsgroups | gmane.comp.python.reportlab.user |
|---|---|
| Message-ID | <[email protected]> |
--===============6416592183070504230==
Content-Type: multipart/alternative;
boundary="Apple-Mail=_247A24E9-6E45-45DA-B332-D90E59CB95FB"
--Apple-Mail=_247A24E9-6E45-45DA-B332-D90E59CB95FB
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
charset=utf-8
First of all, I=E2=80=99d like to thank the ReportLab people for =
releasing such a fabulous open-source toolkit. It truly makes generating =
PDFs so much easier!
The problem I=E2=80=99m reporting affects users that have enabled FIPS =
mode on their systems. In my particular case, it is a RHEL 9.6 system. =
When in FIPS mode, certain cryptographic functions are not permitted =
because of weaknesses in the algorithms. In the case of ReportLab, this =
would be the MD5 function which is used to calculate a document ID and =
is also used to track fonts used, and a few other things, as well as in =
the PDF encryption functions themselves.
When in FIPS mode, running a program will cause an exception similar to:
Traceback (most recent call last):
File "/opt/dftoolkit/bin/annotateCRF", line 82, in main
annotate.build_pdf(plate_filter=3Dargs.plates)
File =
"//opt/dftoolkit/lib/python3.9/site-packages/dftoolkit/annotate.py", =
line 549, in build_pdf
self.doc.build(flowables)
File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 1062, in build
self._startBuild(filename,canvasmaker)
File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 1032, in _startBuild
self.canv =3D =
self._makeCanvas(filename=3Dfilename,canvasmaker=3Dcanvasmaker)
File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 992, in _makeCanvas
canv =3D canvasmaker(filename or self.filename,
File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py", =
line 320, in __init__
self._doc =3D pdfdoc.PDFDocument(compression=3DpageCompression,
File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py",=
line 137, in __init__
sig =3D self.signature =3D md5()
ValueError: [digital envelope routines] unsupported
Most of the uses of MD5, aside from the use in the actual PDF =
encryption, appear not to be security related. In Python 3.9, the =
hashlib functions can be passed a keyword argument called =
=E2=80=98usedforsecurity=E2=80=99 (defaulting to True) that can be set =
to False if the hash algorithm isn=E2=80=99t used for security purposes. =
This allows the use of MD5 hashes even on FIPS enabled systems and =
allows ReportLab to successfully generate PDFs. Passing this keyword =
argument on the older Python 3.6.8 doesn=E2=80=99t cause any ill =
effects.
A small test program demonstrating the hashlib problem on a FIPS enabled =
system, and the fix using usedforsecurity=3DFalse is as follows:
$ more md5test.py
from hashlib import md5
m =3D md5()
m.update(b'This is a test')
print(m.hexdigest())
$ python md5test.py
Traceback (most recent call last):
File "/home/martin/md5test.py", line 2, in <module>
m =3D md5()
ValueError: [digital envelope routines] unsupported
Changing the m=3Dmd5() to m=3Dmd5(usedforsecurity=3DFalse) causes it to =
run successfully:
$ more md5test.py
from hashlib import md5
m =3D md5(usedforsecurity=3DFalse)
m.update(b'This is a test')
print(m.hexdigest())
$ python md5test.py
ce114e4501d2f4e2dcea3e17b546f339
Attached is a patch that adds the usedforsecurity=3DFalse parameter in =
the cases I believe are not security related. Alternatively, a different =
hash function permitted by FIPS could be used. The actual PDF encryption =
code isn=E2=80=99t modified by this patch and it will probably require =
the use of different algorithms to be FIPS compatible.
Thanks for considering this patch,
Martin
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/fontfinder.py =
reportlab/lib/fontfinder.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/lib/fontfinder.py =
2025-06-27 12:37:23.507252855 -0400
+++ reportlab/lib/fontfinder.py 2025-06-29 15:08:52.470092313 -0400
@@ -216,7 +216,7 @@
"""Base this on the directories...same set of directories
should give same cache"""
fsEncoding =3D self._fsEncoding
- hash =3D md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in =
sorted(self._dirs))).hexdigest()
+ hash =3D md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in =
sorted(self._dirs)),usedforsecurity=3DFalse).hexdigest()
from reportlab.lib.utils import get_rl_tempfile
fn =3D get_rl_tempfile('fonts_%s.dat' % hash)
return fn
diff -ru ../venv3.9/lib/python3.9/site-packages/reportlab/lib/utils.py =
reportlab/lib/utils.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/lib/utils.py =
2025-06-27 12:37:23.512252786 -0400
+++ reportlab/lib/utils.py 2025-06-29 15:08:52.473092276 -0400
@@ -55,7 +55,7 @@
_rl_NoneType=3Dtype(None)
strTypes =3D (str,bytes)
def _digester(s):
- return md5(s if isBytes(s) else s.encode('utf8')).hexdigest()
+ return md5(s if isBytes(s) else =
s.encode('utf8'),usedforsecurity=3DFalse).hexdigest()
=20
def asBytes(v,enc=3D'utf8'):
if isinstance(v,bytes): return v
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/cidfonts.py =
reportlab/pdfbase/cidfonts.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/cidfonts.py =
2025-06-27 12:37:23.519252690 -0400
+++ reportlab/pdfbase/cidfonts.py 2025-06-29 15:08:52.668089932 =
-0400
@@ -85,7 +85,7 @@
self.parseCMAPFile(name)
=20
def _hash(self, text):
- hasher =3D md5()
+ hasher =3D md5(usedforsecurity=3DFalse)
hasher.update(text)
return hasher.digest()
=20
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py =
reportlab/pdfbase/pdfdoc.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py =
2025-06-27 12:37:23.520252676 -0400
+++ reportlab/pdfbase/pdfdoc.py 2025-06-29 15:08:52.672089884 -0400
@@ -134,7 +134,7 @@
self.setCompression(compression)
self._pdfVersion =3D pdfVersion
# signature for creating PDF ID
- sig =3D self.signature =3D md5()
+ sig =3D self.signature =3D md5(usedforsecurity=3DFalse)
sig.update(b"a reportlab document")
self._timeStamp =3D TimeStamp(self.invariant)
cat =3D self._timeStamp.t
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py =
reportlab/pdfgen/canvas.py
--- ../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py =
2025-06-27 12:37:23.523252635 -0400
+++ reportlab/pdfgen/canvas.py 2025-06-29 15:08:52.786088514 -0400
@@ -1131,9 +1131,9 @@
"""
#check if we've done this one already...
if isUnicode(command):
- rawName =3D 'PS' + =
hashlib.md5(command.encode('utf-8')).hexdigest()
+ rawName =3D 'PS' + =
hashlib.md5(command.encode('utf-8'),usedforsecurity=3DFalse).hexdigest()
else:
- rawName =3D 'PS' + hashlib.md5(command).hexdigest()
+ rawName =3D 'PS' + =
hashlib.md5(command,usedforsecurity=3DFalse).hexdigest()
regName =3D self._doc.getXObjectName(rawName)
psObj =3D self._doc.idToObject.get(regName, None)
if not psObj:
--Apple-Mail=_247A24E9-6E45-45DA-B332-D90E59CB95FB
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
charset=utf-8
<html><head><meta http-equiv=3D"content-type" content=3D"text/html; =
charset=3Dutf-8"></head><body style=3D"overflow-wrap: break-word; =
-webkit-nbsp-mode: space; line-break: after-white-space;">First of all, =
I=E2=80=99d like to thank the ReportLab people for releasing such a =
fabulous open-source toolkit. It truly makes generating PDFs so much =
easier!<div><br></div><div>The problem I=E2=80=99m reporting affects =
users that have enabled FIPS mode on their systems. In my particular =
case, it is a RHEL 9.6 system. When in FIPS mode, certain cryptographic =
functions are not permitted because of weaknesses in the algorithms. In =
the case of ReportLab, this would be the MD5 function which is used to =
calculate a document ID and is also used to track fonts used, and a few =
other things, as well as in the PDF encryption functions =
themselves.</div><div><br></div><div>When in FIPS mode, running a =
program will cause an exception similar to:</div><div><br></div><div><p =
style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">Traceback (most recent call last):</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> File "/opt/dftoolkit/bin/annotateCRF", line =
82, in main</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> =
annotate.build_pdf(plate_filter=3Dargs.plates)</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> File =
"//opt/dftoolkit/lib/python3.9/site-packages/dftoolkit/annotate.py", =
line 549, in build_pdf</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> self.doc.build(flowables)</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 1062, in build</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> =
self._startBuild(filename,canvasmaker)</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 1032, in _startBuild</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> self.canv =3D =
self._makeCanvas(filename=3Dfilename,canvasmaker=3Dcanvasmaker)</span></p>=
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/platypus/doctemplat=
e.py", line 992, in _makeCanvas</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> canv =3D canvasmaker(filename or =
self.filename,</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py", =
line 320, in __init__</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> self._doc =3D =
pdfdoc.PDFDocument(compression=3DpageCompression,</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> File =
"//opt/dftoolkit/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py",=
line 137, in __init__</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> sig =3D self.signature =3D =
md5()</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">ValueError: [digital envelope routines] =
unsupported</span></p></div><div><br></div><div>Most of the uses of MD5, =
aside from the use in the actual PDF encryption, appear not to be =
security related. In Python 3.9, the hashlib functions can be passed a =
keyword argument called =E2=80=98usedforsecurity=E2=80=99 (defaulting to =
True) that can be set to False if the hash algorithm isn=E2=80=99t used =
for security purposes. This allows the use of MD5 hashes even on FIPS =
enabled systems and allows ReportLab to successfully generate PDFs. =
Passing this keyword argument on the older Python 3.6.8 doesn=E2=80=99t =
cause any ill effects.</div><div><br></div><div>A small test program =
demonstrating the hashlib problem on a FIPS enabled system, and the fix =
using usedforsecurity=3DFalse is as =
follows:</div><div><br></div><div><span style=3D"font-family: Menlo; =
font-size: 11px;">$ more md5test.py</span></div><div><p style=3D"margin: =
0px; font-style: normal; font-variant-caps: normal; font-stretch: =
normal; font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">from hashlib =
import md5</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">m =3D md5()</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">m.update(b'This is a test')</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">print(m.hexdigest())</span></p><p style=3D"margin: =
0px; font-style: normal; font-variant-caps: normal; font-stretch: =
normal; font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures"><br></span></p><p =
style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">$ python md5test.py</span></p><p style=3D"margin: =
0px; font-style: normal; font-variant-caps: normal; font-stretch: =
normal; font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">Traceback (most =
recent call last):</span></p><p style=3D"margin: 0px; font-style: =
normal; font-variant-caps: normal; font-stretch: normal; font-size: =
11px; line-height: normal; font-family: Menlo; font-size-adjust: none; =
font-kerning: auto; font-variant-alternates: normal; =
font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures"> File =
"/home/martin/md5test.py", line 2, in <module></span></p><p =
style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"> m =3D md5()</span></p><p =
style=3D"margin: 0px; font-stretch: normal; font-size: 11px; =
line-height: normal; font-family: Menlo; font-size-adjust: none; =
font-kerning: auto; font-variant-alternates: normal; =
font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">
</span></p><p style=3D"margin: 0px; font-style: normal; =
font-variant-caps: normal; font-stretch: normal; font-size: 11px; =
line-height: normal; font-family: Menlo; font-size-adjust: none; =
font-kerning: auto; font-variant-alternates: normal; =
font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">ValueError: =
[digital envelope routines] unsupported</span></p><p style=3D"margin: =
0px; font-style: normal; font-variant-caps: normal; font-stretch: =
normal; font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: =
no-common-ligatures"><br></span></p></div><div>Changing the m=3Dmd5() to =
m=3Dmd5(usedforsecurity=3DFalse) causes it to run =
successfully:</div><div><br></div><div><p style=3D"margin: 0px; =
font-style: normal; font-variant-caps: normal; font-stretch: normal; =
font-size: 11px; line-height: normal; font-family: Menlo; =
font-size-adjust: none; font-kerning: auto; font-variant-alternates: =
normal; font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">$ more =
md5test.py</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">from hashlib import md5</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">m =3D md5(usedforsecurity=3DFalse)</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">m.update(b'This is a test')</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">print(m.hexdigest())</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures"><br></span></p><p style=3D"margin: 0px; font-style: =
normal; font-variant-caps: normal; font-stretch: normal; font-size: =
11px; line-height: normal; font-family: Menlo; font-size-adjust: none; =
font-kerning: auto; font-variant-alternates: normal; =
font-variant-ligatures: normal; font-variant-numeric: normal; =
font-variant-east-asian: normal; font-variant-position: normal; =
font-variant-emoji: normal; font-feature-settings: normal; =
font-optical-sizing: auto; font-variation-settings: normal;"><span =
style=3D"font-variant-ligatures: no-common-ligatures">$ python =
md5test.py</span></p>
<p style=3D"margin: 0px; font-style: normal; font-variant-caps: normal; =
font-stretch: normal; font-size: 11px; line-height: normal; font-family: =
Menlo; font-size-adjust: none; font-kerning: auto; =
font-variant-alternates: normal; font-variant-ligatures: normal; =
font-variant-numeric: normal; font-variant-east-asian: normal; =
font-variant-position: normal; font-variant-emoji: normal; =
font-feature-settings: normal; font-optical-sizing: auto; =
font-variation-settings: normal;"><span style=3D"font-variant-ligatures: =
no-common-ligatures">ce114e4501d2f4e2dcea3e17b546f339</span></p></div><div=
><span style=3D"font-variant-ligatures: =
no-common-ligatures"><br></span></div><div>Attached is a patch that adds =
the usedforsecurity=3DFalse parameter in the cases I believe are not =
security related. Alternatively, a different hash function permitted by =
FIPS could be used. The actual PDF encryption code isn=E2=80=99t =
modified by this patch and it will probably require the use of different =
algorithms to be FIPS compatible.</div><div><br></div><div>Thanks for =
considering this =
patch,</div><div><br></div><div>Martin</div><div><br></div><div><div><div>=
diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/fontfinder.py =
reportlab/lib/fontfinder.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/fontfinder.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre"> =
</span>2025-06-27 12:37:23.507252855 -0400</div><div>+++ =
reportlab/lib/fontfinder.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"> </span>2025-06-29 15:08:52.470092313 =
-0400</div><div>@@ -216,7 +216,7 @@</div><div> =
"""Base this on the directories...same set of =
directories</div><div> should give same =
cache"""</div><div> fsEncoding =3D =
self._fsEncoding</div><div>- hash =3D =
md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in =
sorted(self._dirs))).hexdigest()</div><div>+ =
hash =3D md5(b''.join(asBytes(_,enc=3DfsEncoding) for _ in =
sorted(self._dirs)),usedforsecurity=3DFalse).hexdigest()</div><div> =
from reportlab.lib.utils import =
get_rl_tempfile</div><div> fn =3D =
get_rl_tempfile('fonts_%s.dat' % hash)</div><div> =
return fn</div><div>diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/utils.py =
reportlab/lib/utils.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/lib/utils.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre"> =
</span>2025-06-27 12:37:23.512252786 -0400</div><div>+++ =
reportlab/lib/utils.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"> </span>2025-06-29 15:08:52.473092276 =
-0400</div><div>@@ -55,7 +55,7 =
@@</div><div> _rl_NoneType=3Dtype(None)</div><div> strTypes =3D =
(str,bytes)</div><div> def _digester(s):</div><div>- =
return md5(s if isBytes(s) else =
s.encode('utf8')).hexdigest()</div><div>+ return md5(s if =
isBytes(s) else =
s.encode('utf8'),usedforsecurity=3DFalse).hexdigest()</div><div> </di=
v><div> def asBytes(v,enc=3D'utf8'):</div><div> =
if isinstance(v,bytes): return v</div><div>diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/cidfonts.py =
reportlab/pdfbase/cidfonts.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/cidfonts.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre"> =
</span>2025-06-27 12:37:23.519252690 -0400</div><div>+++ =
reportlab/pdfbase/cidfonts.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"> </span>2025-06-29 15:08:52.668089932 =
-0400</div><div>@@ -85,7 +85,7 @@</div><div> =
=
self.parseCMAPFile(name)</div><div> </div><div> =
def _hash(self, text):</div><div>- =
hasher =3D md5()</div><div>+ hasher =3D =
md5(usedforsecurity=3DFalse)</div><div> =
hasher.update(text)</div><div> =
return hasher.digest()</div><div> </div><div>diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py =
reportlab/pdfbase/pdfdoc.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfbase/pdfdoc.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre"> =
</span>2025-06-27 12:37:23.520252676 -0400</div><div>+++ =
reportlab/pdfbase/pdfdoc.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"> </span>2025-06-29 15:08:52.672089884 =
-0400</div><div>@@ -134,7 +134,7 @@</div><div> =
self.setCompression(compression)</div><div> =
self._pdfVersion =3D pdfVersion</div><div> =
# signature for creating PDF ID</div><div>- =
sig =3D self.signature =3D md5()</div><div>+ =
sig =3D self.signature =3D =
md5(usedforsecurity=3DFalse)</div><div> =
sig.update(b"a reportlab document")</div><div> =
self._timeStamp =3D =
TimeStamp(self.invariant)</div><div> =
cat =3D self._timeStamp.t</div><div>diff -ru =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py =
reportlab/pdfgen/canvas.py</div><div>--- =
../venv3.9/lib/python3.9/site-packages/reportlab/pdfgen/canvas.py<span =
class=3D"Apple-tab-span" style=3D"white-space:pre"> =
</span>2025-06-27 12:37:23.523252635 -0400</div><div>+++ =
reportlab/pdfgen/canvas.py<span class=3D"Apple-tab-span" =
style=3D"white-space:pre"> </span>2025-06-29 15:08:52.786088514 =
-0400</div><div>@@ -1131,9 +1131,9 @@</div><div> =
"""</div><div> #check if =
we've done this one already...</div><div> =
if isUnicode(command):</div><div>- =
rawName =3D 'PS' + =
hashlib.md5(command.encode('utf-8')).hexdigest()</div><div>+ =
rawName =3D 'PS' + =
hashlib.md5(command.encode('utf-8'),usedforsecurity=3DFalse).hexdigest()</=
div><div> else:</div><div>- =
rawName =3D 'PS' + =
hashlib.md5(command).hexdigest()</div><div>+ =
rawName =3D 'PS' + =
hashlib.md5(command,usedforsecurity=3DFalse).hexdigest()</div><div> =
regName =3D =
self._doc.getXObjectName(rawName)</div><div> =
psObj =3D self._doc.idToObject.get(regName, None)</div><div> =
if not =
psObj:</div></div></div><div><br></div></body></html>=
--Apple-Mail=_247A24E9-6E45-45DA-B332-D90E59CB95FB--
--===============6416592183070504230==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline