test: tested loading ECDSA key pair from text

This commit is contained in:
zihluwang
2025-01-26 20:05:06 +08:00
parent 5f9ea34af0
commit cf7e5efa62
7 changed files with 105 additions and 11 deletions
+64
View File
@@ -0,0 +1,64 @@
# KeyLoader
KeyLoader provides utility methods to load keys from pem-formatted key texts.
## ECDSA-based algorithm
### Generate key pair
#### Generate private key
Generate a private key by `genpkey` command provided by OpenSSL:
```shell
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out ec_private_key.pem
```
The output of this command is a file called `ec_private_key.pem` and its content looks like the
following:
```text
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgs79JlARgXEf6EDV7
+PHQCTHEMtqIoHOy1GZ1+ynQJ6yhRANCAARkA7GRY2i4gg8qx0XViAXUP9cPw9pn
Jg1wfrQ41FaMyqVBejNYxvaLtamErF/ySimnjafMJ+VZCh34lBj6Ez8R
-----END PRIVATE KEY-----
```
#### Generate public key by private key
Export public key from private key with `ec` command provided by OpenSSL:
```shell
openssl ec -in ec_private_key.pem -pubout -out ec_public_key.pem
```
The output of this command is a file called `ec_public_key.pem` and its content looks like the
following:
```text
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZAOxkWNouIIPKsdF1YgF1D/XD8Pa
ZyYNcH60ONRWjMqlQXozWMb2i7WphKxf8kopp42nzCflWQod+JQY+hM/EQ==
-----END PUBLIC KEY-----
```
#### Convert private key to EC formats which could be acceptable by Java
Java's `PKCS8EncodedKeySpec` requires the private key to be in PKCS#8 format, while OpenSSL by
default generates private keys in traditional PEM format. To convert the private key, run the
following command:
```shell
openssl pkcs8 -topk8 -inform PEM -outform PEM -in ec_private_key.pem -out ec_private_key_pkcs8.pem -nocrypt
```
The converted private key will look like this:
```text
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgs79JlARgXEf6EDV7
+PHQCTHEMtqIoHOy1GZ1+ynQJ6yhRANCAARkA7GRY2i4gg8qx0XViAXUP9cPw9pn
Jg1wfrQ41FaMyqVBejNYxvaLtamErF/ySimnjafMJ+VZCh34lBj6Ez8R
-----END PRIVATE KEY-----
```
@@ -55,12 +55,13 @@ public class EcKeyLoader implements KeyLoader {
/** /**
* Initialise a key loader for EC-based algorithms. * Initialise a key loader for EC-based algorithms.
*
* @throws NoSuchAlgorithmException if no {@code Provider} supports a {@code KeyFactorySpi}
* implementation for the specified algorithm
*/ */
public EcKeyLoader() throws NoSuchAlgorithmException { public EcKeyLoader() {
try {
this.keyFactory = KeyFactory.getInstance("EC"); this.keyFactory = KeyFactory.getInstance("EC");
} catch (NoSuchAlgorithmException e) {
throw new KeyLoadingException(e);
}
} }
/** /**
@@ -76,8 +77,8 @@ public class EcKeyLoader implements KeyLoader {
try { try {
// remove all unnecessary parts of the pem key text // remove all unnecessary parts of the pem key text
pemKeyText = pemKeyText pemKeyText = pemKeyText
.replaceAll("-----BEGIN EC PRIVATE KEY-----", "") .replaceAll("-----BEGIN (EC )?PRIVATE KEY-----", "")
.replaceAll("-----END EC PRIVATE KEY-----", "") .replaceAll("-----END (EC )?PRIVATE KEY-----", "")
.replaceAll("\n", ""); .replaceAll("\n", "");
var decodedKeyString = Base64.getDecoder().decode(pemKeyText); var decodedKeyString = Base64.getDecoder().decode(pemKeyText);
var keySpec = new PKCS8EncodedKeySpec(decodedKeyString); var keySpec = new PKCS8EncodedKeySpec(decodedKeyString);
@@ -106,8 +107,8 @@ public class EcKeyLoader implements KeyLoader {
try { try {
// remove all unnecessary parts of the pem key text // remove all unnecessary parts of the pem key text
pemKeyText = pemKeyText pemKeyText = pemKeyText
.replaceAll("-----BEGIN EC PUBLIC KEY-----", "") .replaceAll("-----BEGIN (EC )?PUBLIC KEY-----", "")
.replaceAll("-----END EC PUBLIC KEY-----", "") .replaceAll("-----END (EC )?PUBLIC KEY-----", "")
.replaceAll("\n", ""); .replaceAll("\n", "");
var keyBytes = Base64.getDecoder().decode(pemKeyText); var keyBytes = Base64.getDecoder().decode(pemKeyText);
var spec = new X509EncodedKeySpec(keyBytes); var spec = new X509EncodedKeySpec(keyBytes);
@@ -115,7 +116,7 @@ public class EcKeyLoader implements KeyLoader {
if (key instanceof ECPublicKey publicKey) { if (key instanceof ECPublicKey publicKey) {
return publicKey; return publicKey;
} else { } else {
throw new KeyLoadingException("Unable to load private key from pem-formatted key text."); throw new KeyLoadingException("Unable to load public key from pem-formatted key text.");
} }
} catch (InvalidKeySpecException e) { } catch (InvalidKeySpecException e) {
throw new KeyLoadingException("Key spec is invalid.", e); throw new KeyLoadingException("Key spec is invalid.", e);
@@ -17,13 +17,27 @@
package com.onixbyte.security; package com.onixbyte.security;
import com.onixbyte.security.impl.EcKeyLoader;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class KeyPairLoaderTest { public class KeyPairLoaderTest {
@Test @Test
public void test() { public void test() {
var keyLoader = new EcKeyLoader();
var privateKey = keyLoader.loadPrivateKey("""
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgs79JlARgXEf6EDV7
+PHQCTHEMtqIoHOy1GZ1+ynQJ6yhRANCAARkA7GRY2i4gg8qx0XViAXUP9cPw9pn
Jg1wfrQ41FaMyqVBejNYxvaLtamErF/ySimnjafMJ+VZCh34lBj6Ez8R
-----END PRIVATE KEY-----
""");
var publicKey = keyLoader.loadPublicKey("""
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZAOxkWNouIIPKsdF1YgF1D/XD8Pa
ZyYNcH60ONRWjMqlQXozWMb2i7WphKxf8kopp42nzCflWQod+JQY+hM/EQ==
-----END PUBLIC KEY-----
""");
} }
} }
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgs79JlARgXEf6EDV7
+PHQCTHEMtqIoHOy1GZ1+ynQJ6yhRANCAARkA7GRY2i4gg8qx0XViAXUP9cPw9pn
Jg1wfrQ41FaMyqVBejNYxvaLtamErF/ySimnjafMJ+VZCh34lBj6Ez8R
-----END PRIVATE KEY-----
@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgs79JlARgXEf6EDV7
+PHQCTHEMtqIoHOy1GZ1+ynQJ6yhRANCAARkA7GRY2i4gg8qx0XViAXUP9cPw9pn
Jg1wfrQ41FaMyqVBejNYxvaLtamErF/ySimnjafMJ+VZCh34lBj6Ez8R
-----END PRIVATE KEY-----
@@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZAOxkWNouIIPKsdF1YgF1D/XD8Pa
ZyYNcH60ONRWjMqlQXozWMb2i7WphKxf8kopp42nzCflWQod+JQY+hM/EQ==
-----END PUBLIC KEY-----
@@ -43,6 +43,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
import java.time.Duration; import java.time.Duration;