diff --git a/src/addons/hwtoken/src/main/java/ee/ria/xroad/signer/tokenmanager/token/helper/KeyPairHelper.java b/src/addons/hwtoken/src/main/java/ee/ria/xroad/signer/tokenmanager/token/helper/KeyPairHelper.java
index 1499420bf0..0cd8127433 100644
--- a/src/addons/hwtoken/src/main/java/ee/ria/xroad/signer/tokenmanager/token/helper/KeyPairHelper.java
+++ b/src/addons/hwtoken/src/main/java/ee/ria/xroad/signer/tokenmanager/token/helper/KeyPairHelper.java
@@ -46,6 +46,7 @@ static KeyPairHelper of(KeyAlgorithm algorithm) {
return switch (algorithm) {
case RSA -> RsaKeyPairHelper.INSTANCE;
case EC -> EcKeyPairHelper.INSTANCE;
+ case EdDSA -> null; //TODO #EDDSA proper impl
};
}
}
diff --git a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentSigner.java b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentSigner.java
index 4218e0a02a..67d6612340 100644
--- a/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentSigner.java
+++ b/src/central-server/admin-service/globalconf-generator/src/main/java/org/niis/xroad/cs/admin/globalconf/generator/DirectoryContentSigner.java
@@ -78,7 +78,7 @@ private byte[] sign(String keyId, byte[] data) {
var signatureAlgorithmId = getSignAlgorithmId(keyId, signDigestAlgorithmId);
- byte[] digest = calculateDigest(signatureAlgorithmId.digest(), data);
+ byte[] digest = signatureAlgorithmId.prehashable() ? calculateDigest(signatureAlgorithmId.digest(), data) : data;
return Signatures.useAsn1DerFormat(signatureAlgorithmId, signerProxy.sign(keyId, signatureAlgorithmId, digest));
}
diff --git a/src/central-server/admin-service/infra-api-rest/src/main/java/org/niis/xroad/cs/admin/rest/api/mapper/ConfigurationSigningKeyDtoMapper.java b/src/central-server/admin-service/infra-api-rest/src/main/java/org/niis/xroad/cs/admin/rest/api/mapper/ConfigurationSigningKeyDtoMapper.java
index 63ead04ef3..ae5f0e9f01 100644
--- a/src/central-server/admin-service/infra-api-rest/src/main/java/org/niis/xroad/cs/admin/rest/api/mapper/ConfigurationSigningKeyDtoMapper.java
+++ b/src/central-server/admin-service/infra-api-rest/src/main/java/org/niis/xroad/cs/admin/rest/api/mapper/ConfigurationSigningKeyDtoMapper.java
@@ -26,12 +26,15 @@
*/
package org.niis.xroad.cs.admin.rest.api.mapper;
+import ee.ria.xroad.common.crypto.identifier.KeyAlgorithm;
+
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingConstants;
import org.niis.xroad.cs.admin.api.converter.GenericUniDirectionalMapper;
import org.niis.xroad.cs.admin.api.domain.ConfigurationSigningKeyWithDetails;
import org.niis.xroad.cs.openapi.model.ConfigurationSigningKeyDto;
+import org.niis.xroad.cs.openapi.model.KeyAlgorithmDto;
@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface ConfigurationSigningKeyDtoMapper extends
@@ -46,4 +49,12 @@ public interface ConfigurationSigningKeyDtoMapper extends
@Mapping(target = "keyHash", ignore = true)
ConfigurationSigningKeyDto toTarget(ConfigurationSigningKeyWithDetails model);
+ default KeyAlgorithmDto toTarget(KeyAlgorithm model) {
+ return switch (model){
+ case RSA -> KeyAlgorithmDto.RSA;
+ case EC -> KeyAlgorithmDto.EC;
+ case EdDSA -> KeyAlgorithmDto.ED_DSA;
+ };
+ }
+
}
diff --git a/src/central-server/openapi-model/src/main/resources/openapi-definition.yaml b/src/central-server/openapi-model/src/main/resources/openapi-definition.yaml
index 7c1a888ecc..8409704058 100644
--- a/src/central-server/openapi-model/src/main/resources/openapi-definition.yaml
+++ b/src/central-server/openapi-model/src/main/resources/openapi-definition.yaml
@@ -3630,6 +3630,7 @@ components:
enum:
- RSA
- EC
+ - EdDSA
example: RSA
format: enum
type: string
diff --git a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/EdDsaKeyManager.java b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/EdDsaKeyManager.java
new file mode 100644
index 0000000000..972bdcceb8
--- /dev/null
+++ b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/EdDsaKeyManager.java
@@ -0,0 +1,74 @@
+/*
+ * The MIT License
+ * Copyright (c) 2018 Estonian Information System Authority (RIA),
+ * Nordic Institute for Interoperability Solutions (NIIS), Population Register Centre (VRK)
+ * Copyright (c) 2015-2017 Estonian Information System Authority (RIA), Population Register Centre (VRK)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package ee.ria.xroad.common.crypto;
+
+import ee.ria.xroad.common.crypto.identifier.KeyAlgorithm;
+import ee.ria.xroad.common.crypto.identifier.SignAlgorithm;
+
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.spec.RSAPublicKeySpec;
+
+public final class EdDsaKeyManager extends AbstractKeyManager {
+
+ // Use no digesting algorithm, since the input data is already a digest
+ private static final SignAlgorithm SIGNATURE_ALGORITHM = SignAlgorithm.ofName("Ed25519");
+ private static final KeyAlgorithm CRYPTO_ALGORITHM = KeyAlgorithm.EdDSA;
+
+ EdDsaKeyManager() {
+ super(CRYPTO_ALGORITHM);
+ }
+
+ /**
+ * Generates X509 encoded public key bytes from a given modulus and
+ * public exponent.
+ * @param modulus the modulus
+ * @param publicExponent the public exponent
+ * @return generated public key bytes
+ * @throws Exception if any errors occur
+ */
+ public byte[] generateX509PublicKey(BigInteger modulus, BigInteger publicExponent) throws Exception {
+ RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
+ return generateX509PublicKey(rsaPublicKeySpec);
+ }
+
+ @Override
+ public SignAlgorithm getSoftwareTokenSignAlgorithm() {
+ return SIGNATURE_ALGORITHM;
+ }
+
+ @Override
+ public SignAlgorithm getSoftwareTokenKeySignAlgorithm() {
+ return SignAlgorithm.ED25519;
+ }
+
+ @Override
+ public KeyPair generateKeyPair() throws Exception {
+ KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(SignAlgorithm.ED25519.name());
+
+ return keyPairGen.generateKeyPair();
+ }
+}
diff --git a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/KeyManagers.java b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/KeyManagers.java
index e3419a4cb9..5879b47f5a 100644
--- a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/KeyManagers.java
+++ b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/KeyManagers.java
@@ -34,7 +34,8 @@
public final class KeyManagers {
private static final Map BY_TYPE = Map.of(
KeyAlgorithm.RSA, new RsaKeyManager(),
- KeyAlgorithm.EC, new EcKeyManager()
+ KeyAlgorithm.EC, new EcKeyManager(),
+ KeyAlgorithm.EdDSA, new EdDsaKeyManager()
);
public static KeyManager getFor(String keyAlgorithm) {
diff --git a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/SignDataPreparer.java b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/SignDataPreparer.java
index c3c04cc92a..360d7b6994 100644
--- a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/SignDataPreparer.java
+++ b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/SignDataPreparer.java
@@ -36,7 +36,7 @@ public sealed interface SignDataPreparer {
static SignDataPreparer of(SignAlgorithm algorithm) {
return switch (algorithm.signMechanism()) {
case CKM_RSA_PKCS -> RsaPkcsPreparer.INSTANCE;
- case CKM_RSA_PKCS_PSS, CKM_ECDSA -> NoopPreparer.INSTANCE;
+ case CKM_RSA_PKCS_PSS, CKM_ECDSA, CKM_EDDSA -> NoopPreparer.INSTANCE;
};
}
diff --git a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/KeyAlgorithm.java b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/KeyAlgorithm.java
index a14cfd1346..a8c3751868 100644
--- a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/KeyAlgorithm.java
+++ b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/KeyAlgorithm.java
@@ -25,5 +25,7 @@
package ee.ria.xroad.common.crypto.identifier;
public enum KeyAlgorithm {
- RSA, EC
+ RSA, EC, EdDSA
+ /* TODO #EDDSA probably better just have 2 different types for Es25519 and Ed448,
+ even java KeyPairGenerator takes specific name and not general type code as for EC/RSA */
}
diff --git a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/SignAlgorithm.java b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/SignAlgorithm.java
index 89f81a3f84..97907de4a5 100644
--- a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/SignAlgorithm.java
+++ b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/SignAlgorithm.java
@@ -38,6 +38,7 @@
import static ee.ria.xroad.common.crypto.identifier.DigestAlgorithm.SHA384;
import static ee.ria.xroad.common.crypto.identifier.DigestAlgorithm.SHA512;
import static ee.ria.xroad.common.crypto.identifier.SignMechanism.CKM_ECDSA;
+import static ee.ria.xroad.common.crypto.identifier.SignMechanism.CKM_EDDSA;
import static ee.ria.xroad.common.crypto.identifier.SignMechanism.CKM_RSA_PKCS;
import static ee.ria.xroad.common.crypto.identifier.SignMechanism.CKM_RSA_PKCS_PSS;
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA1;
@@ -45,6 +46,7 @@
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA256;
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA384;
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_ECDSA_SHA512;
+import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519;
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1;
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256;
import static org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1;
@@ -75,6 +77,8 @@ public sealed interface SignAlgorithm {
SignAlgorithm SHA384_WITH_ECDSA = INDEX.create("SHA384withECDSA", ALGO_ID_SIGNATURE_ECDSA_SHA384, CKM_ECDSA, SHA384);
SignAlgorithm SHA512_WITH_ECDSA = INDEX.create("SHA512withECDSA", ALGO_ID_SIGNATURE_ECDSA_SHA512, CKM_ECDSA, SHA512);
+ SignAlgorithm ED25519 = INDEX.create("Ed25519", ALGO_ID_SIGNATURE_EDDSA_ED25519, CKM_EDDSA, null);
+
String name();
String uri();
@@ -87,6 +91,10 @@ default KeyAlgorithm algorithm() {
SignMechanism signMechanism();
+ default boolean prehashable(){
+ return digest() != null;
+ }
+
static SignAlgorithm ofUri(String uri) {
return INDEX.ofUri(uri).orElseGet(() -> new UnknownSignAlgorithm(null, uri));
}
@@ -177,6 +185,9 @@ private Optional ofName(String name) {
}
private Optional ofDigestAndSignMechanism(DigestAlgorithm algorithm, SignMechanism mechanism) {
+ if(CKM_EDDSA.equals(mechanism)){
+ return Optional.of(SignAlgorithm.ED25519);
+ }
return Optional.ofNullable(byDigestAndMechanism.get(new Key(algorithm, mechanism)));
}
diff --git a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/SignMechanism.java b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/SignMechanism.java
index b58676edb3..d9e5aa8d22 100644
--- a/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/SignMechanism.java
+++ b/src/common/common-core/src/main/java/ee/ria/xroad/common/crypto/identifier/SignMechanism.java
@@ -27,7 +27,8 @@
public enum SignMechanism {
CKM_RSA_PKCS(KeyAlgorithm.RSA),
CKM_RSA_PKCS_PSS(KeyAlgorithm.RSA),
- CKM_ECDSA(KeyAlgorithm.EC);
+ CKM_ECDSA(KeyAlgorithm.EC),
+ CKM_EDDSA(KeyAlgorithm.EdDSA);
private final KeyAlgorithm algorithm;
diff --git a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/converter/KeyConverter.java b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/converter/KeyConverter.java
index a83d9b1c05..09419ec198 100644
--- a/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/converter/KeyConverter.java
+++ b/src/security-server/admin-service/application/src/main/java/org/niis/xroad/securityserver/restapi/converter/KeyConverter.java
@@ -116,6 +116,7 @@ private KeyAlgorithm mapKeyAlgorithm(String signMechanismName) {
return switch (SignMechanism.valueOf(signMechanismName).keyAlgorithm()) {
case RSA -> KeyAlgorithm.RSA;
case EC -> KeyAlgorithm.EC;
+ case EdDSA -> KeyAlgorithm.ED_DSA; //TODO #EDDSA proper impl
};
}
diff --git a/src/security-server/openapi-model/src/main/resources/META-INF/openapi-definition.yaml b/src/security-server/openapi-model/src/main/resources/META-INF/openapi-definition.yaml
index a2bf2d0a8c..3ff09eccba 100644
--- a/src/security-server/openapi-model/src/main/resources/META-INF/openapi-definition.yaml
+++ b/src/security-server/openapi-model/src/main/resources/META-INF/openapi-definition.yaml
@@ -6741,6 +6741,7 @@ components:
enum:
- RSA
- EC
+ - EdDSA
example: RSA
format: enum
type: string
diff --git a/src/signer-protocol/src/main/proto/key_service.proto b/src/signer-protocol/src/main/proto/key_service.proto
index 42dd3201d0..094d13299a 100644
--- a/src/signer-protocol/src/main/proto/key_service.proto
+++ b/src/signer-protocol/src/main/proto/key_service.proto
@@ -55,6 +55,7 @@ enum Algorithm {
ALGORITHM_UNKNOWN = 0;
RSA = 1;
EC = 2;
+ EdDSA = 3;
}
message GetKeyIdForCertHashReq {
diff --git a/src/signer/core/src/intTest/java/org/niis/xroad/signer/test/glue/SignerParallelStepDefs.java b/src/signer/core/src/intTest/java/org/niis/xroad/signer/test/glue/SignerParallelStepDefs.java
index 5c5bfd0758..e50bbacd73 100644
--- a/src/signer/core/src/intTest/java/org/niis/xroad/signer/test/glue/SignerParallelStepDefs.java
+++ b/src/signer/core/src/intTest/java/org/niis/xroad/signer/test/glue/SignerParallelStepDefs.java
@@ -59,6 +59,7 @@ public void digestCanBeSignedUsingKeyFromToken(String keyName, String friendlyNa
var signAlgorithm = switch (SignMechanism.valueOf(key.getSignMechanismName()).keyAlgorithm()) {
case RSA -> SHA256_WITH_RSA;
case EC -> SHA256_WITH_ECDSA;
+ case EdDSA -> null; //TODO #EDDSA proper impl
};
doConcurrentSign(() -> {
diff --git a/src/signer/core/src/intTest/java/org/niis/xroad/signer/test/glue/SignerStepDefs.java b/src/signer/core/src/intTest/java/org/niis/xroad/signer/test/glue/SignerStepDefs.java
index 67dabaa8a3..6a4909b469 100644
--- a/src/signer/core/src/intTest/java/org/niis/xroad/signer/test/glue/SignerStepDefs.java
+++ b/src/signer/core/src/intTest/java/org/niis/xroad/signer/test/glue/SignerStepDefs.java
@@ -417,6 +417,7 @@ public void digestCanBeSignedUsingKeyFromToken(String keyName, String friendlyNa
var signAlgorithm = switch (SignMechanism.valueOf(key.getSignMechanismName()).keyAlgorithm()) {
case RSA -> SHA256_WITH_RSA;
case EC -> SHA256_WITH_ECDSA;
+ case EdDSA -> null; //TODO #EDDSA proper impl
};
SignerProxy.sign(key.getId(), signAlgorithm, calculateDigest(SHA256, digest.getBytes(UTF_8)));
@@ -454,6 +455,7 @@ public void certificateCanBeSignedUsingKeyFromToken(String keyName, String frien
var signAlgorithm = switch (algorithm) {
case RSA -> SHA256_WITH_RSA;
case EC -> SHA256_WITH_ECDSA;
+ case EdDSA -> null; //TODO #EDDSA proper impl
};
final byte[] bytes = SignerProxy.signCertificate(key.getId(), signAlgorithm, "CN=CS", publicKey);
@@ -471,6 +473,7 @@ public void sign(String keyName, String friendlyName) throws Exception {
var signAlgorithm = switch (SignMechanism.valueOf(key.getSignMechanismName()).keyAlgorithm()) {
case RSA -> SHA256_WITH_RSA;
case EC -> SHA256_WITH_ECDSA;
+ case EdDSA -> null; //TODO #EDDSA proper impl
};
byte[] bytes = SignerProxy.sign(key.getId(), signAlgorithm, calculateDigest(SHA256, digest.getBytes(UTF_8)));
diff --git a/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/module/SoftwareModuleWorker.java b/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/module/SoftwareModuleWorker.java
index 20e229d558..96a72753c4 100644
--- a/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/module/SoftwareModuleWorker.java
+++ b/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/module/SoftwareModuleWorker.java
@@ -27,6 +27,7 @@
import ee.ria.xroad.common.SystemProperties;
import ee.ria.xroad.common.crypto.identifier.KeyAlgorithm;
+import ee.ria.xroad.common.crypto.identifier.SignMechanism;
import ee.ria.xroad.signer.protocol.dto.TokenInfo;
import ee.ria.xroad.signer.tokenmanager.TokenManager;
import ee.ria.xroad.signer.tokenmanager.token.AbstractTokenWorker;
@@ -46,7 +47,8 @@ public class SoftwareModuleWorker extends AbstractModuleWorker {
private static final List TOKENS = List.of(new SoftwareTokenType(
Map.of(
KeyAlgorithm.EC, SystemProperties.getSofTokenEcSignMechanism(),
- KeyAlgorithm.RSA, SystemProperties.getSoftTokenRsaSignMechanism()
+ KeyAlgorithm.RSA, SystemProperties.getSoftTokenRsaSignMechanism(),
+ KeyAlgorithm.EdDSA, SignMechanism.CKM_EDDSA //TODO #EDDSA proper impl
)
));
diff --git a/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/token/AbstractTokenWorker.java b/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/token/AbstractTokenWorker.java
index c1ac34da3b..44b5f56314 100644
--- a/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/token/AbstractTokenWorker.java
+++ b/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/token/AbstractTokenWorker.java
@@ -220,6 +220,7 @@ protected KeyAlgorithm mapAlgorithm(Algorithm algorithm) {
return switch (algorithm) {
case RSA, ALGORITHM_UNKNOWN, UNRECOGNIZED -> KeyAlgorithm.RSA;
case EC -> KeyAlgorithm.EC;
+ case EdDSA -> KeyAlgorithm.EdDSA;
};
}
diff --git a/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/token/SoftwareTokenWorker.java b/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/token/SoftwareTokenWorker.java
index 48f68063ba..1a838e5415 100644
--- a/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/token/SoftwareTokenWorker.java
+++ b/src/signer/core/src/main/java/ee/ria/xroad/signer/tokenmanager/token/SoftwareTokenWorker.java
@@ -127,7 +127,9 @@ public class SoftwareTokenWorker extends AbstractTokenWorker {
SignAlgorithm.SHA1_WITH_ECDSA,
SignAlgorithm.SHA256_WITH_ECDSA,
SignAlgorithm.SHA384_WITH_ECDSA,
- SignAlgorithm.SHA512_WITH_ECDSA
+ SignAlgorithm.SHA512_WITH_ECDSA,
+
+ SignAlgorithm.ED25519
);
private static final String UNSUPPORTED_SIGN_ALGORITHM = "unsupported_sign_algorithm";