OpenAS2 / OpenAs2App

OpenAS2 is a java-based implementation of the EDIINT AS2 standard. It is intended to be used as a server. It is extremely configurable and supports a wide variety of signing and encryption algorithms.
https://sourceforge.net/projects/openas2/
GNU General Public License v3.0
185 stars 136 forks source link

Improvement: EC (Elliptic-curve) Private Key Decryption Compatibility for Incoming Messages #403

Closed szabarna closed 6 hours ago

szabarna commented 1 week ago

Description

This pull request enhances OpenAS2’s BCCryptoHelper.java to support decryption for messages when the recipient’s private key is based on Elliptic Curve (EC) cryptography, in addition to the existing support for RSA. Previously, OpenAS2’s decryption functionality could only handle RSA-based private keys, leading to limitations when users relied on EC-based cryptography for incoming message decryption. Problem Statement

In OpenAS2, incoming messages are encrypted by the sender using the recipient’s public certificate, and the recipient decrypts them using their private key. However, if the recipient’s private key was based on EC cryptography, OpenAS2’s BCCryptoHelper could not properly identify or process the decryption. This limitation prevented any message encrypted with the recipient’s EC-based public key from being decrypted by OpenAS2, thus obstructing the ability to receive encrypted messages for organizations using EC private keys. Solution

The updated BCCryptoHelper.java extends the existing decryption method to support both RSA and EC-based private keys:

Key Algorithm Detection: The decryption method now dynamically checks whether the recipient’s private key uses RSA or EC cryptography and selects the appropriate decryption algorithm.
Recipient Type Handling: Different recipient types (KeyTransRecipientInformation for RSA and KeyAgreeRecipientInformation for EC) are identified and processed accordingly. This ensures that the correct algorithm is used for each private key type without additional configuration.

Changes Made

Modified the decrypt function in BCCryptoHelper.java to support EC-based keys alongside RSA by adding checks for the key algorithm and using appropriate recipient types for each.
Added debug logging to assist in diagnosing recipient matching issues, showing details about recipient IDs and types when a match fails.

Benefits

Broadened Cryptography Support: OpenAS2 now supports decryption with both RSA and EC-based private keys, allowing greater flexibility and security options for users.
Compatibility for Modern Cryptographic Standards: As more organizations adopt EC cryptography, OpenAS2 users can leverage EC-based security without hindrance.

Testing

This update has been successfully tested with both RSA- and EC-based cryptography setups to confirm that OpenAS2 can now decrypt incoming messages regardless of the recipient’s key type. Summary

The enhancement broadens OpenAS2’s decryption capability, enabling it to support both RSA and EC-based private keys, which aligns with modern cryptographic standards and allows users greater flexibility in their security configurations. This approach resolves the previous limitations with EC cryptography, ensuring that OpenAS2 remains compatible with a wider range of encryption standards in secure communications.

uhurusurfa commented 6 days ago

I can only imagine that the Windows failures are a result of some change or error in configuring Windows instances deployed for running Java testing. I will check in again on Monday and try to rerun the failed tests.

szabarna commented 3 days ago

Hi! I realized this needs more testing and also i am updating the encryption part as well to support EC based private keys. Currently the test between A and B partner is failing, i will commit my changes when i got over this problem and tested it throughly.

szabarna commented 1 day ago

Should i extend the getOutputEncryptor function to handle OID-s for EC as well? What i mean is rather than hardcoding the encryption algorithm here:

        JceKeyAgreeRecipientInfoGenerator recipientGenerator
                = new JceKeyAgreeRecipientInfoGenerator(
                    CMSAlgorithm.ECMQV_SHA256KDF, 
                    keypair.getPrivate(), 
                    keypair.getPublic(),
                    CMSAlgorithm.AES128_WRAP
                    ).setProvider("BC");

        recipientGenerator.addRecipient((X509Certificate) receiverCert);

        encryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC)
        .setProvider("BC").build();

I will leave the keyAgreementOID as it is: CMSAlgorithm.ECMQV_SHA256KDF.

But the encryptionOID should come from the partnership, in this context i am talking about: CMSAlgorithm.AES128_WRAP and CMSAlgorithm.AES128_CBC

What are your thoughts?

uhurusurfa commented 10 hours ago

It is looking good.

Yes please use the "algorithm" parameter passed into the encrypt() method for the EC by doing this on line 316:

encryptor = new JceCMSContentEncryptorBuilder(getOutputEncryptor(algorithm));