-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add S/MIME encryption #5488
Comments
Okay, looking at this... OpenSSL has PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, int flags); So your API then looks more like:
Where the above API would reject any non-RSA PKCS1v15 X.509 certificates with a TypeError. We need to be able to derive an We've discussed whether we should establish an enum of ciphersuites for algorithm selection in some of our serialization APIs (right now we only allow class EncryptionAlgorithm(Enum):
AES_128_CBC = "AES-128 with CBC mode"
AES_256_CBC = "AES-256 with CBC mode"
TripleDES_CBC = "3DES with CBC mode" Unfortunately, much like our issues with general key serialization, we're limited in the set of algorithms we can actually use...and the most usefully interoperable ones are by far the worst. |
Yes, I agree.. interoperability is a huge problem here. S/MIME 4.0 (RFC 8551) defines two modern content encryption algorithms (AES-GCM, ChaCha20-Poly1305) that are far better. Obviously these aren't yet broadly available/implemented.. but somebody has to start.. right?! :-D
I'm not entirely sure/convinced (yet) that using this would be the ideal way to go here. |
The idea of support extremely modern encryption in order to nudge people
towards modern things appeals to me :-)
…On Sun, Oct 25, 2020 at 12:13 PM frennkie ***@***.***> wrote:
Yes, I agree.. interoperability is a huge problem here.
S/MIME 4.0 (RFC 8551 <https://tools.ietf.org/html/rfc8551#section-2.7>)
defines two modern content encryption algorithms (AES-GCM,
ChaCha20-Poly1305) that are far better. Obviously these aren't yet broadly
available/implemented.. but somebody has to start.. right?! :-D
PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER
*cipher, int flags);
I'm not entirely sure/convinced (*yet*) that using this would be the
ideal way to go here.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#5488 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAAGBDEBYX34QVIRSPZED3SMRFBRANCNFSM4ST2PKGA>
.
--
All that is necessary for evil to succeed is for good people to do nothing.
|
If there is an alternative to building these structures (and supporting modern encryption) I'd much rather go down that path than |
As I indicated in the initial description of this issue I have already managed to encrypt an S/MIME message using pure python and Thanks for pointing out the Rust ASN.1 issue. I hadn't seen that yet (as I'm pretty new to this project). |
Discussion is not enabled for this repo, so I ask here. Currently we use some patches on https://github.com/balena/python-smime which is unmaintained: from smime.block import get_cipher, AES
from smime.cert import certs_from_pem
from asn1crypto import cms
# some patch
def _encrypt(self, data):
padded_data = self._pad(data, self.block_size)
if not isinstance(padded_data, bytes):
padded_data = padded_data.encode('utf-8')
encrypted_content = self._encryptor.update(padded_data) + self._encryptor.finalize()
return {
'content_type': 'data',
'content_encryption_algorithm': {
'algorithm': self.algorithm,
'parameters': self._iv
},
'encrypted_content': encrypted_content
}
@staticmethod
def _pad(s, block_size):
n = block_size - len(s) % block_size
return s + n * (chr(n) if isinstance(s, str) else bytes([n]))
AES._pad = _pad
AES.encrypt = _encrypt
def encrypt(message, certs, algorithm='aes256_cbc'):
block_cipher = get_cipher(algorithm)
if block_cipher == None:
raise ValueError('Unknown block algorithm')
recipient_infos = []
for cert_file in certs:
for cert in certs_from_pem(cert_file):
recipient_info = cert.recipient_info(block_cipher.session_key)
if recipient_info == None:
raise ValueError('Unknown public-key algorithm')
recipient_infos.append(recipient_info)
return cms.ContentInfo({
'content_type': 'enveloped_data',
'content': {
'version': 'v0',
'recipient_infos': recipient_infos,
'encrypted_content_info': block_cipher.encrypt(message)
}
}).dump()
encrypt(<DATA>, [<BASE64 CERT>]) It does the job but recently we noticed it is so slow. Is there alternative to do this with |
@alex @reaperhulk If we wanted to support for S/MIME encryption, which algorithms do we want to support? In S/MIME v3 (the same version we support for signing), the RFC states:
cc @woodruffw |
I believe there's a later RFC that adds AES and I'd be inclined to support only that as a first pass if we're going to implement this at all. I'm strongly against RC2 (barring some very large reason why we need compatibility but absolutely no security) and weakly against 3DES. |
True, looking at the S/MIME v3.2 RFCs:
So for the first pass, we could support |
I think that’s a reasonable path, yes. |
This was completed in #10889 |
Following up on the comment in #1621 I would like to suggest to add the possibility to use
pyca/cryptography
for encrypting ("envelope") S/MIME messages.I have been using this in past projects:
As far as I see it most parts needed in order to encrypt a message are already present in
cryptography
:What I have not found/solved yet is that an equivalent to the
cms.RecipientInfo
structure from asn1crypto would be required.Similar to the recent addition of S/MIME signing an API could look like this:
In the end a combination of a first signed and then enveloped message would also be great.
The text was updated successfully, but these errors were encountered: