Hello. I'm using Spring Boot 2.5.3 (and Java 13 atm with OpenSaml 4.1.1) and - using autoconfiguration - I'm unable to use Elliptic curve private key as relaying party signing credentials' private key - it looks like only RSA keys are supported. I'm integrating with our govermnent's IDP and the usage of elliptic keys is mandatory.

Here is a "trimmed" stacktrace:

(....omitted....)
Caused by: java.lang.IllegalArgumentException: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Invalid RSA private key
    at org.springframework.security.converter.RsaKeyConverters.lambda$pkcs8$0(RsaKeyConverters.java:88)
    at org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyRegistrationConfiguration.readPrivateKey(Saml2RelyingPartyRegistrationConfiguration.java:138)
    ... 75 common frames omitted
Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Invalid RSA private key
    at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:251)
    at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390)
    at org.springframework.security.converter.RsaKeyConverters.lambda$pkcs8$0(RsaKeyConverters.java:85)
    ... 76 common frames omitted
Caused by: java.security.InvalidKeyException: Invalid RSA private key
    at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.parseKeyBits(RSAPrivateCrtKeyImpl.java:285)
    at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:342)
    at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355)
    at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:130)
    at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:80)
    at java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:356)
    at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:247)
    ... 78 common frames omitted
Caused by: java.io.IOException: Version must be 0
    at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.parseKeyBits(RSAPrivateCrtKeyImpl.java:263)
    ... 84 common frames omitted

My application.yml has only one relying party:

spring:
  thymeleaf:
    cache: false
  security:
    saml2:
      network:
        read-timeout: 8000
        connect-timeout: 4000
      relyingparty:
        registration:
          samlexample:
            signing:
              credentials:
                - private-key-location: "classpath:credentials/SIGN_EC_privatekey_pkcs8.pem"
                  certificate-location: "classpath:credentials/SIGN_EC_certificate.pem"
            identityprovider:
              entity-id: some-environment.login.gov.pl
              singlesignon:
                sign-request: true
                url: https://some-environment.login.gov.pl/login/SingleSignOnService
              metadata-uri: https://some-environment.login.gov.pl/login/metadata

My current workaround is to "shadow" the configuration class (copy & paste) and hardcode loading the EC keys myself.

Thanks in advance for looking into this. Lukasz

Comment From: ljader

From what I've seen in other Spring projects, this looks more like a feature request than a bug: https://github.com/spring-projects/spring-security-oauth/issues/1159 https://github.com/spring-projects/spring-security-oauth/pull/1223

Comment From: snicoll

@ljader this doesn't look supported by Spring Security (as the stacktrace in your original comment shows) so I don't think we can do anything about it. I am going to close this now and we can follow-up with the Spring Security team if a change turned out to be necessary on our side.

Comment From: ljader

@snicoll this is the place where the RSA credential loading is hardcoded https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java#L138 so it's in Spring Boot, NOT in Spring security

Comment From: philwebb

@ljader Are you able to share the code that you use the load the elliptic curve private key in your current work-around? I assume it's just a case of using KeyFactory.getInstance("ECDSA") rather than KeyFactory.getInstance("RSA")?

@jzheaux Are there any classes in Spring Security similar to RsaKeyConverters but with ECDSA support? Perhaps we need a general KeyConverters class that isn't RSA specific? We could do the conversion directly in Spring Boot, but it feels more like a Spring Security concern.

Comment From: mhalbritter

We can use our PemPrivateKeyParser here, which supports all kinds of PKCS8 keys.