Skip to content
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

invalid RSA CSR generated with 3.0 branch #1522

Open
afatsoum opened this issue Sep 4, 2020 · 5 comments
Open

invalid RSA CSR generated with 3.0 branch #1522

afatsoum opened this issue Sep 4, 2020 · 5 comments

Comments

@afatsoum
Copy link

afatsoum commented Sep 4, 2020

When using the following snippet to generate a basic CSR from RSA key, it seems the wrong encryption type is set..

Some issues..

  • signature algorithm was set to rsassaPss instead sha256WithRSAEncryption
  • public key type was set to rsassaPss instead of rsaEncryption

With 3.0 branch do we need to somehow set the rsaEncryption type??

$privKey = PublicKeyLoader::load($pem, $password = false);
$x509 = new X509();
$x509->setPrivateKey($privKey);	
$x509->setDNProp('id-at-organizationName', 'phpseclib demo cert');
$signCsr = $x509->signCSR("sha256WithRSAEncryption");
echo $x509->saveCSR($signCsr);

Here is a sample RSA key used for this procedure which is the value for $pem

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAh9glYzWG41RNxs4dc5CvMzJZSj969ElD1NW8/QscKGwApnvz
e5IN2smZ1aqBAJFWiPermQTUzXnZOrMksZDsyV8wZWosgsW/kzxLalo3XNlPSfCn
Gpnh72/PqSKlH2wp7YDgvRTtpkwLNJDuYuMp4hMKoscuGEvGINGoArESTF/r6yuU
q58V0C+Hh5p4detzcmSm9X6A5TDaZIb7wmjLtbxPi3uk4hUYwEbPjBpz7828LwHS
kHKRfXrxfGIZM+PZIG37c/xh14lJycTjSgBkcD6QSAdBm8xRAKrpNBQYoOKazTz3
5pd8vY5khPTzkXQ7IHxBOCaSMJj9nxyVUSwhjwIDAQABAoIBAAZyudOZdI/15Q2D
7W+sme2IxksdqpGXFmydCvk39KUR+1p+AynhS8uiSr+lGpFcVMGCgCBuwSII6O2r
zqs6gUwElmnMPh5bklofZNmcF9JgdS54wCy3pc1MWozPCDClpk60WtIMkx/dHDQy
kYv29+hFlflff5d+gUtkXynT1MOrQOtAsrndKWBk4KehCKK1scJU8ApfQSQB02X9
JMg9wF9zXBrDpSqYn4zFGpSSTquHccfLfwVt+vh4gSg1iGEky7qXTYDPV73f+PYy
qzvjUMjXZj09lIoFN9YQ5MQsCTgXyxhqHG2DDMwMiLRABtVVI0cIPXCBZgUJ4pRR
8af7NwECgYEAlDWo7CL1WO+mTRNHDgwl+PzRk4yx9qhmpsogqXSkLKX8EZqMtOs/
fPGekx5t1wfo+hjpIhh2cfg1wp3XbBI3z1akGfAFggBWKq9H4dfnntaqtgr6ozaj
xCZl8EtWlQKqBeuCjLqtOfRZxRMhZWzmX3a6TiUASQqcLSDSu1WW4ScCgYEA6qRC
rwAdJpnEZH/ZUacKVI46eZpTljIDJluH21wLA1v/zu4h6teaptZcxMFB4h2P9a/+
7GU72uYK1UbC3m2E+7s+ZjVpSTc/KVE1OQ2VkN9wwQcgmUFekcFJWPxsqLWmWx5u
Z7kH4l3JZIF468AQ0UG7j/r7DP3uRLJlMrM8LVkCgYAp7pyiYqmjxfn5KJEb6lf8
ABuTcWUQckjIu7tN9lBUyYltuZpBvaUyxnGlEiDli7lguReMq/sm96DONTYzv1vG
765yIDSOuWWnofvma91+VSHra2PKNbVT08FXoRkYA67zCdTf2BkWoombdnQmbA8p
xz+iyFkyUSwqoHS+x9JuVQKBgQCJ6bIoGfEIVyjPyTV6gKvZtx83ijXG+e5QBUx8
6kSu3MwmXGEjH0aO+T/dhZmrxaRvy9oSKA5eQwfrA4RWKBkZvJyYhpwzpH1DU6/s
sMdQN4SWcBIBAiMLmIf7/aIAJ4R32hMac+7mZimRIWhpaKJ53CDaJ7KXmEkLp69D
dYXRQQKBgGaMdxHcblJi7blmCVW3bC/lFRprdssLCCWi+VGqPfrt51JXbTBwZk1q
n9x50Q26cgqMC1g6zFYjdBpa0/EpmGhhER4FZxZhpseLHFsResdS/Xutc6UumuMs
7Z7Fjf8/hh/qS3UwDbeVf3EoAd7E8sEO9skwfKnHaTs+HknLpno6
-----END RSA PRIVATE KEY-----

Here is a sample broken CSR generated from the above

-----BEGIN CERTIFICATE REQUEST-----
MIICjzCCAXkCAQAwHjEcMBoGA1UECgwTcGhwc2VjbGliIGRlbW8gY2VydDCCAVIw
PQYJKoZIhvcNAQEKMDCgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJ
YIZIAWUDBAIBowMCAQEDggEPADCCAQoCggEBAIfYJWM1huNUTcbOHXOQrzMyWUo/
evRJQ9TVvP0LHChsAKZ783uSDdrJmdWqgQCRVoj3q5kE1M152TqzJLGQ7MlfMGVq
LILFv5M8S2paN1zZT0nwpxqZ4e9vz6kipR9sKe2A4L0U7aZMCzSQ7mLjKeITCqLH
LhhLxiDRqAKxEkxf6+srlKufFdAvh4eaeHXrc3JkpvV+gOUw2mSG+8Joy7W8T4t7
pOIVGMBGz4wac+/NvC8B0pBykX168XxiGTPj2SBt+3P8YdeJScnE40oAZHA+kEgH
QZvMUQCq6TQUGKDims089+aXfL2OZIT085F0OyB8QTgmkjCY/Z8clVEsIY8CAwEA
ATALBgkqhkiG9w0BAQoDggEBAFsmgL2AeKECnBbfbA7Ia36TBLg7eeaoh8DHBSv1
EzT3MUIl4P9k+i22u2D6bLv35m6z0522xzw42fwKoAp8275nYouJMTpnoU+6FIgJ
KepE6CxZyGr8+n/rRvY39tm9SaWHYLpstd2+CRk4BSuiB76V2yryQimX1kH7i1dQ
u8Bsfwd8WAVjTFmfFlTwxeJGN9lONKnLa3ZnJKO4oGnqhIKiLZiFjuDLnGCHFIAg
AXMZ0Ym76lXhjNBJ8mRbjKTYBNUm8jPdbsiVstB6lCCO944iZIJMywAojVxI6kKl
0MIG8W8JXeXa5/TwTfcgZWwbbIzb5XpkPQk6WitV5BU6NhA=
-----END CERTIFICATE REQUEST-----

Here is the OPENSSL output

C:\test>openssl req -in badcsr.txt -text -noout
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: O = phpseclib demo cert
        Subject Public Key Info:
            Public Key Algorithm: rsassaPss
                RSA-PSS Public-Key: (2048 bit)
                Modulus:
                    00:87:d8:25:63:35:86:e3:54:4d:c6:ce:1d:73:90:
                    af:33:32:59:4a:3f:7a:f4:49:43:d4:d5:bc:fd:0b:
                    1c:28:6c:00:a6:7b:f3:7b:92:0d:da:c9:99:d5:aa:
                    81:00:91:56:88:f7:ab:99:04:d4:cd:79:d9:3a:b3:
                    24:b1:90:ec:c9:5f:30:65:6a:2c:82:c5:bf:93:3c:
                    4b:6a:5a:37:5c:d9:4f:49:f0:a7:1a:99:e1:ef:6f:
                    cf:a9:22:a5:1f:6c:29:ed:80:e0:bd:14:ed:a6:4c:
                    0b:34:90:ee:62:e3:29:e2:13:0a:a2:c7:2e:18:4b:
                    c6:20:d1:a8:02:b1:12:4c:5f:eb:eb:2b:94:ab:9f:
                    15:d0:2f:87:87:9a:78:75:eb:73:72:64:a6:f5:7e:
                    80:e5:30:da:64:86:fb:c2:68:cb:b5:bc:4f:8b:7b:
                    a4:e2:15:18:c0:46:cf:8c:1a:73:ef:cd:bc:2f:01:
                    d2:90:72:91:7d:7a:f1:7c:62:19:33:e3:d9:20:6d:
                    fb:73:fc:61:d7:89:49:c9:c4:e3:4a:00:64:70:3e:
                    90:48:07:41:9b:cc:51:00:aa:e9:34:14:18:a0:e2:
                    9a:cd:3c:f7:e6:97:7c:bd:8e:64:84:f4:f3:91:74:
                    3b:20:7c:41:38:26:92:30:98:fd:9f:1c:95:51:2c:
                    21:8f
                Exponent: 65537 (0x10001)
                PSS parameter restrictions:
                  Hash Algorithm: sha256
                  Mask Algorithm: mgf1 with sha256
                  Minimum Salt Length: 0x14 (default)
                  Trailer Field: 0x01
        Attributes:
    Signature Algorithm: rsassaPss         (INVALID PSS PARAMETERS)

         7b:52:79:ef:3b:97:e0:bc:1e:57:96:cd:92:67:c3:c5:2e:f9:
         3e:45:d3:4b:2a:e1:c9:c9:40:1e:3e:34:6b:05:2e:1f:da:0f:
         37:3d:66:29:ff:c0:a7:e1:e5:7d:42:80:f0:db:55:5e:2d:05:
         68:3a:4d:16:d9:6a:39:aa:ab:8b:b7:1f:54:8e:9b:71:fc:ce:
         82:41:c3:23:52:6c:d0:cb:26:91:87:f2:41:b7:ea:03:f6:de:
         0a:fe:39:37:f9:3c:87:b5:ef:e4:29:79:2b:2c:42:ec:bb:d7:
         6b:ed:5b:6a:49:ac:fa:f5:6c:2c:6a:d4:d2:47:c0:c3:69:52:
         ef:63:08:6a:ce:ee:04:57:5f:a9:b3:aa:2b:33:aa:38:f8:cd:
         c9:e7:44:7d:97:b2:f8:af:d9:fa:90:c7:b8:9d:ca:99:c8:09:
         e3:3f:b7:93:aa:a6:33:a3:a7:49:7f:46:1b:d8:ec:03:f8:b4:
         e9:eb:49:2a:37:13:14:7b:9d:e8:38:a1:b3:43:59:25:2b:eb:
         29:7e:08:92:bb:0f:37:88:4d:94:b7:38:ea:38:88:b4:7b:2c:
         a8:99:4e:ae:eb:c0:d9:21:d2:9c:fe:28:3f:8a:89:02:1f:c7:
         fd:8f:5a:87:c4:83:5b:02:fd:83:a3:43:b3:52:fe:0c:ef:29:
         ad:95:b4:7c
@terrafrost
Copy link
Member

terrafrost commented Sep 6, 2020

phpseclib 3.0 changes up how things work. If you look at the source code you'll note that the functions no longer have that $signatureAlgorihtm parameter whereas in the 2.0 branch they do:

3.0 / master branch:

public function sign($issuer, $subject)

2.0 branch:

function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption')

The way it works in the 3.0 / master branch is that you set the preferred parameters in the private key itself. So in this case you'd do this:

$privKey = PublicKeyLoader::load($pem);
$privKey = $privKey->withPadding(RSA::SIGNATURE_PKCS1);

Also, keep in mind that if you're not setting a password in $privKey = PublicKeyLoader::load($pem, $password = false); you can remove that last parameter. I only include it in my examples so you know how to set a password.

It's doing PSS, as is, because PSS is th default padding scheme that RSA keys utilize (because it's the more secure one, albeit the less frequently used one)

@terrafrost
Copy link
Member

Note that this is necessary now that phpseclib supports keys other than just RSA keys. What happens if you're trying to use an EC key with sha1WithRSAEncryption? Obviously that doesn't make a lot of sense! So what should it do in that scenario? Throw an exception?

If that $signatureAlgorithm is going to be optional it makes sense that it look at the key type to determine what the $signatureAlgorithm ought to be, which is what it's now doing.

@afatsoum
Copy link
Author

afatsoum commented Sep 6, 2020

@terrafrost not sure I follow you. Other than the keysize/curve there isn't much else you can take from the key. In the case I have an RSA key and want to sign a CSR with different hash algorithm sha1, sha224, sha256, sha384 & sha512. You cannot determine this from the key itself. How can I choose which algorithm to sign with?

Same deal with ECDSA, you can determine the curve from the key i.e prime256v1 but the hashing algorithm needs to specified during the signing of the CSR i.e. ecdsa-with-sha256 / sha384 etc

Are you saying you are setting a default hashing algorithm based on the key type (RSA/ECDSA)? If so that makes sense but am I also able to set something other than the default?

@terrafrost
Copy link
Member

terrafrost commented Sep 6, 2020

How can I choose which algorithm to sign with?

$key = $key->withHash('sha512');

Remember, key objects in phpseclib 3.0 are immutable and yet it's the keys you sign with. phpseclib doesn't employ do things like Java, wherein you'd do something like $cipher = Cipher::getInstance('RSA/ECB/OAEPWithSHA-256AndMGF1Padding'); $cipher->init(Cipher::DECRYPT_MODE, $privateKey);. No, with phpseclib you do $privateKey->decrypt('...');.

So how do you set the hash with that ? With 1.0 / 2.0 you'd do $privateKey->setHash('sha256') but 3.0 / master have immutable keys so obviously that doesn't work. So what you do is $privateKey = $privateKey->withHash('sha256').

Where public key crypto is concerned phpseclib 3.0 / master is a complete paradigm shift from 1.0 / 2.0.

@afatsoum
Copy link
Author

afatsoum commented Sep 6, 2020

Thank you for clarifying. I like the paradigm shift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants