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

[Bug] Active Directory (Authentication=ActiveDirectoryServicePrincipalCertificate). Cannot parse the PVK, PVK file does not contain the correct header..does it not support encryped keys? #2530

Open
muskaan62 opened this issue Oct 22, 2024 · 9 comments · May be fixed by #2532

Comments

@muskaan62
Copy link

muskaan62 commented Oct 22, 2024

Question

ActiveDirectoryServicePrincipalCertificate Authentication with client certifiicate private key and private key associated with password is not working.

String jdbcUrl = "jdbc:sqlserver://******;" +
                "database=*******;" +
                "encrypt=true;"+
                "trustServerCertificate=true;" +
                "authentication=ActiveDirectoryServicePrincipalCertificate;"+
                "user=*****;"+
                "clientCertificate= ******;"+
                "clientKey=******;"+
                "clientKeyPassword=*****";

I am trying to connect with azuresql db with the above url using (clientcert,private key,password) for authentication
Note(clientcert with private key is working)
client cert with password also working.
only the above combination is giving the below error..I have verified the private key as well it contains valid header

-----BEGIN ENCRYPTED PRIVATE KEY-----

Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: Failed to authenticate the user xxxxxxxx in Active Directory (Authentication=ActiveDirectoryServicePrincipalCertificate). Cannot parse the PVK, PVK file does not contain the correct header.
	at com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils.getCorrectedException(SQLServerMSAL4JUtils.java:488)
	at com.microsoft.sqlserver.jdbc.SQLServerMSAL4JUtils.getSqlFedAuthTokenPrincipalCertificate(SQLServerMSAL4JUtils.java:319)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.getFedAuthToken(SQLServerConnection.java:6089)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.onFedAuthInfo(SQLServerConnection.java:6012)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.processFedAuthInfo(SQLServerConnection.java:5846)
	at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onFedAuthInfo(tdsparser.java:346)
	at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:130)
	at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:42)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:6905)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:5451)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:5383)
	at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7775)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:4408)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:3845)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:3402)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:3211)
	at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1979)
	at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1267)
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:251)

tested with latest driver also 12.8.0.jre11
Is it a bug in driver?

use below steps to create certificate with private key and privatekey password


Generate a Private Key (with password):
openssl genpkey -algorithm RSA -aes256 -out private.key -pass pass:<your-password>
Create a Certificate Signing Request (CSR):
openssl req -new -key private.key -out request.csr -passin pass:<your-password>
Generate a Self-Signed Certificate:
openssl x509 -req -days 365 -in request.csr -signkey private.key -out certificate.crt -passin pass:<your-password>

Relevant Issues and Pull Requests

@muskaan62 muskaan62 changed the title [QUESTION] Active Directory (Authentication=ActiveDirectoryServicePrincipalCertificate). Cannot parse the PVK, PVK file does not contain the correct header..does it not support encryped keys? [Bug] Active Directory (Authentication=ActiveDirectoryServicePrincipalCertificate). Cannot parse the PVK, PVK file does not contain the correct header..does it not support encryped keys? Oct 23, 2024
@lilgreenbird
Copy link
Contributor

lilgreenbird commented Oct 23, 2024

hi @muskaan62

I don't see the code you used to connect but the url you included above doesn't look correct. Please see this doc for an example on how to connect using ActiveDirectoryServicePrincipalCertificate authentication mode.

@muskaan62
Copy link
Author

muskaan62 commented Oct 24, 2024

hi @muskaan62

I don't see the code you used to connect but the url you included above doesn't look correct. Please see this doc for an example on how to connect using ActiveDirectoryServicePrincipalCertificate authentication mode.

@lilgreenbird The code

try (Connection connection = DriverManager.getConnection(jdbcUrl);
             Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT* from TestTable")) {

            if (rs.next()) {
                System.out.println("Id: " + rs.getString(1));
                System.out.println("Name: " + rs.getString(2));
            }
        }

can u please mention whats the wrong in the url if it is trustServerCertificate and encrypt one then keeping both true also give same error...also the attach doc is not showing anything its pointing to github repo only.I am kinda block on this.

@muskaan62
Copy link
Author

muskaan62 commented Oct 24, 2024

@lilgreenbird I think the bug is in this method https://github.com/microsoft/mssql-jdbc/blob/main/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCertificateUtils.java#L397 which use to decrypt the encrypted private key .
I clone the driver code and replace the above method with the below logic
https://stackoverflow.com/questions/69027323/reading-pem-encoded-encrypted-private-key-from-file-in-java . its working as expected.
can u please fix this issue ASAP. as it is blocking our enhancement feature.

@lilgreenbird
Copy link
Contributor

I'm sorry it looks like there was a c&p issue the link in my prev post was wrong, I've now fixed it. The example uses SQLServerDataSource but it's the same idea in URL form, you can see in the sample what properties is needed for ActiveDirectoryServicePrincipalCertificate auth.

We also have junit test which tests ActiveDirectoryServicePrincipalCertificate fyi.

@muskaan62
Copy link
Author

muskaan62 commented Oct 25, 2024

@lilgreenbird I am using the correct properties in URL form. And the test you provide is only for testing certificate auth without any password.
let me tell you in details
As per this doc https://learn.microsoft.com/en-us/sql/connect/jdbc/connecting-using-azure-active-directory-authentication?view=sql-server-ver16#connect-using-activedirectoryserviceprincipalcertificate-authentication-mode we can authenticate via ActiveDirectoryServicePrincipal certificate in this four ways.(jdbc url prop allowed https://learn.microsoft.com/en-us/sql/connect/jdbc/setting-the-connection-properties?view=sql-server-ver16 )

  1. client certificate without password (the test you provide for this scenario) [working]
  2. client certificate with password [working]
  3. client certificate with private key [working]
  4. client certificate with private key and key password (i.e means encrypted key) [bug]
    The above 3 ways are working fine but fourth is not ..so for that i clone the jdbc driver code in my machine and debug and observe the logic use for decrypting the private key for the fourth option is not correct so i replaced with another logic(gave details in prev commet) and try to authenticate and its working ..please check my previous comment. its a bug in the code..if URL has any issues it wouldn't have work for any option and when i replace the logic also it wouldnt have work for fourth option..but its working that means no issue with the URL.

@muskaan62
Copy link
Author

muskaan62 commented Oct 30, 2024

@lilgreenbird I try to raise the PR for this issue but looks like i dont have perms to create PR.
though i have created a patch for the fix below.. I tried to upload patch file here for the fix somehow its not uploading so put that in the text file you rename it to .patch if you are considering the fix.
fixissue2530.txt

@lilgreenbird
Copy link
Contributor

hi @muskaan62

Thanks, what errors are you getting whehn you tried to create a PR? this is open source so anyone should be able to create a PR and we've had contributions from various users in the past. You should be able to create a PR here

@muskaan62
Copy link
Author

muskaan62 commented Nov 1, 2024

@lilgreenbird facing this error Image

I try to fork the repo and raise PR #2532

@github-project-automation github-project-automation bot moved this to To be triaged in MSSQL JDBC Nov 6, 2024
@Jeffery-Wasty Jeffery-Wasty moved this from To be triaged to In progress in MSSQL JDBC Nov 6, 2024
@Jeffery-Wasty Jeffery-Wasty moved this from In progress to Under Peer Review in MSSQL JDBC Dec 11, 2024
@j2-z
Copy link

j2-z commented Dec 13, 2024

I'm encountering the same issue. Seems currently only encrypted private key in PKCS#1 format is supported by MSSQL JDBC. I tried converting the private key PEM to PKCS#1 format and encrypted it. This worked and might be a workaround for now.

openssl rsa -in key.pem -out key-pkcs1.pem -traditional 
openssl rsa -in key-pkcs1.pem -out key-pkcs1-encrypted.pem -aes256 -traditional

I'm using mssql-jdbc:12.8.1.jre8 and bouncycastle dependecies are required. Looking at the comments in #2532, looks like the bouncycastle dependecies would be dropped after JDK 8... which means the workaround may not be able to work on JDK 11+.

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

Successfully merging a pull request may close this issue.

3 participants