Java源码示例:com.webauthn4j.data.attestation.statement.COSEAlgorithmIdentifier

示例1
@Override
public AttestationType validate(RegistrationObject registrationObject) {
    if (!supports(registrationObject)) {
        throw new IllegalArgumentException("Specified format is not supported by " + this.getClass().getName());
    }

    PackedAttestationStatement attestationStatement = (PackedAttestationStatement) registrationObject.getAttestationObject().getAttestationStatement();
    byte[] sig = attestationStatement.getSig();
    COSEAlgorithmIdentifier alg = attestationStatement.getAlg();
    byte[] attrToBeSigned = getAttToBeSigned(registrationObject);
    // If x5c is present,
    if (attestationStatement.getX5c() != null) {
        return validateX5c(registrationObject, attestationStatement, sig, alg, attrToBeSigned);
    }
    // If x5c is not present, self attestation is in use.
    else {
        return validateSelfAttestation(registrationObject, sig, alg, attrToBeSigned);
    }
}
 
示例2
private AttestationType validateX5c(RegistrationObject registrationObject, PackedAttestationStatement attestationStatement, byte[] sig, COSEAlgorithmIdentifier alg, byte[] attrToBeSigned) {
    if (attestationStatement.getX5c() == null || attestationStatement.getX5c().isEmpty()) {
        throw new BadAttestationStatementException("No attestation certificate is found in packed attestation statement.");
    }

    // Verify that sig is a valid signature over the concatenation of authenticatorData and clientDataHash
    // using the attestation public key in x5c with the algorithm specified in alg.
    if (!verifySignature(attestationStatement.getX5c().getEndEntityAttestationCertificate().getCertificate().getPublicKey(), alg, sig, attrToBeSigned)) {
        throw new BadSignatureException("`sig` in attestation statement is not valid signature over the concatenation of authenticatorData and clientDataHash.");
    }
    // Verify that x5c meets the requirements in §8.2.1 Packed attestation statement certificate requirements.
    attestationStatement.getX5c().getEndEntityAttestationCertificate().validate();

    // If x5c contains an extension with OID 1.3.6.1.4.1.45724.1.1.4 (id-fido-gen-ce-aaguid) verify that
    // the value of this extension matches the aaguid in authenticatorData.
    X509Certificate attestationCertificate = attestationStatement.getX5c().getEndEntityAttestationCertificate().getCertificate();
    AAGUID aaguidInCertificate = extractAAGUIDFromAttestationCertificate(attestationCertificate);
    AAGUID aaguid = registrationObject.getAttestationObject().getAuthenticatorData().getAttestedCredentialData().getAaguid();
    if (aaguidInCertificate != AAGUID.NULL && !Objects.equals(aaguidInCertificate, aaguid)) {
        throw new BadAttestationStatementException("AAGUID in attestation certificate doesn't match the AAGUID in authenticatorData.");
    }

    // If successful, return attestation type BASIC and attestation trust path x5c.
    return AttestationType.BASIC;
}
 
示例3
/**
 * Constructor for key pair
 *
 * @param keyId     keyId
 * @param algorithm algorithm
 * @param keyOps    keyOps
 * @param curve     curve
 * @param x         x
 * @param y         y
 * @param d         d
 */
@SuppressWarnings("squid:S00107")
@JsonCreator
public EC2COSEKey(
        @JsonProperty("2") byte[] keyId,
        @JsonProperty("3") COSEAlgorithmIdentifier algorithm,
        @JsonProperty("4") List<COSEKeyOperation> keyOps,
        @JsonProperty("-1") Curve curve,
        @JsonProperty("-2") byte[] x,
        @JsonProperty("-3") byte[] y,
        @JsonProperty("-4") byte[] d) {
    super(keyId, algorithm, keyOps, null);
    this.curve = curve;
    this.x = x;
    this.y = y;
    this.d = d;
}
 
示例4
/**
 * create from uncompressed ECC 256-bit key
 *
 * @param publicKey publicKey
 * @return {@link EC2COSEKey}
 */
public static EC2COSEKey createFromUncompressedECCKey(byte[] publicKey) {
    if (publicKey.length != 65) {
        throw new IllegalArgumentException("publicKey must be 65 bytes length");
    }
    byte[] x = Arrays.copyOfRange(publicKey, 1, 1 + 32);
    byte[] y = Arrays.copyOfRange(publicKey, 1 + 32, 1 + 32 + 32);
    return new EC2COSEKey(
            null,
            COSEAlgorithmIdentifier.ES256,
            null,
            Curve.SECP256R1,
            x,
            y,
            null
    );
}
 
示例5
/**
 * Constructor for key pair
 *
 * @param keyId     keyId
 * @param algorithm algorithm
 * @param keyOps    keyOps
 * @param n         the RSA modulus n
 * @param e         the RSA public exponent e
 * @param d         the RSA private exponent d
 * @param p         the prime factor p of n
 * @param q         the prime factor q of n
 * @param dP        dP is d mod (p - 1)
 * @param dQ        dQ is d mod (q - 1)
 * @param qInv      qInv is the CRT coefficient q^(-1) mod p
 */
@SuppressWarnings("squid:S00107")
@JsonCreator
public RSACOSEKey(
        @JsonProperty("2") byte[] keyId,
        @JsonProperty("3") COSEAlgorithmIdentifier algorithm,
        @JsonProperty("4") List<COSEKeyOperation> keyOps,
        @JsonProperty("-1") byte[] n,
        @JsonProperty("-2") byte[] e,
        @JsonProperty("-3") byte[] d,
        @JsonProperty("-4") byte[] p,
        @JsonProperty("-5") byte[] q,
        @JsonProperty("-6") byte[] dP,
        @JsonProperty("-7") byte[] dQ,
        @JsonProperty("-8") byte[] qInv
) {
    super(keyId, algorithm, keyOps, null);
    this.n = n;
    this.e = e;
    this.d = d;
    this.p = p;
    this.q = q;
    this.dP = dP;
    this.dQ = dQ;
    this.qInv = qInv;
}
 
示例6
@Test
void equals_hashCode_test() {
    String rpId = "example.com";
    Challenge challenge = new DefaultChallenge();

    PublicKeyCredentialParameters publicKeyCredentialParameters
            = new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256);
    PublicKeyCredentialCreationOptions instanceA = new PublicKeyCredentialCreationOptions(
            new PublicKeyCredentialRpEntity(rpId, "example.com"),
            new PublicKeyCredentialUserEntity(),
            challenge,
            Collections.singletonList(publicKeyCredentialParameters)
    );
    PublicKeyCredentialCreationOptions instanceB = new PublicKeyCredentialCreationOptions(
            new PublicKeyCredentialRpEntity(rpId, "example.com"),
            new PublicKeyCredentialUserEntity(),
            challenge,
            Collections.singletonList(publicKeyCredentialParameters)
    );

    assertAll(
            () -> assertThat(instanceA).isEqualTo(instanceB),
            () -> assertThat(instanceA).hasSameHashCodeAs(instanceB)
    );
}
 
示例7
private static EC2CredentialPublicKey createECCredentialPublicKey() {
    return new EC2CredentialPublicKey(
            null,
            COSEAlgorithmIdentifier.ES256,
            null,
            null,
            Curve.SECP256R1,
            new byte[32],
            new byte[32]
    );
}
 
示例8
/**
 * Add PublicKeyCredParam
 *
 * @param type the {@link PublicKeyCredentialType}
 * @param alg  the {@link COSEAlgorithmIdentifier}
 * @return the {@link PublicKeyCredParamsConfig}
 */
public PublicKeyCredParamsConfig addPublicKeyCredParams(PublicKeyCredentialType type, COSEAlgorithmIdentifier alg) {
    Assert.notNull(type, "type must not be null");
    Assert.notNull(alg, "alg must not be null");

    publicKeyCredentialParameters.add(new PublicKeyCredentialParameters(type, alg));
    return this;
}
 
示例9
@Test
public void equals_hashCode_test() {
    PublicKeyCredentialRpEntity rpEntity = new PublicKeyCredentialRpEntity("rpId", "rpName", "rpIcon");
    WebAuthnPublicKeyCredentialUserEntity userEntity = new WebAuthnPublicKeyCredentialUserEntity(Base64UrlUtil.encodeToString("userHandle".getBytes()), "username");
    Challenge challenge = new DefaultChallenge();
    List<PublicKeyCredentialParameters> pubKeyCredParams = Collections.singletonList(new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256));
    Long registrationTimeout = 1000L;
    List<String> credentialIds = Collections.singletonList("credentialId");
    AuthenticationExtensionsClientInputs<RegistrationExtensionClientInput<?>> authenticationExtensionsClientInputs = new AuthenticationExtensionsClientInputs<>();
    AttestationOptions instanceA = new AttestationOptions(rpEntity, userEntity, challenge, pubKeyCredParams, registrationTimeout, credentialIds, authenticationExtensionsClientInputs);
    AttestationOptions instanceB = new AttestationOptions(rpEntity, userEntity, challenge, pubKeyCredParams, registrationTimeout, credentialIds, authenticationExtensionsClientInputs);

    assertThat(instanceA).isEqualTo(instanceB);
    assertThat(instanceA).hasSameHashCodeAs(instanceB);
}
 
示例10
@Test
void create_with_alg_test(){
    EC2COSEKey key;
    key= EC2COSEKey.create((ECPrivateKey) ECUtil.createKeyPair().getPrivate(), COSEAlgorithmIdentifier.ES256);
    assertThat(key.getAlgorithm()).isEqualTo(COSEAlgorithmIdentifier.ES256);
    key = EC2COSEKey.create((ECPublicKey) ECUtil.createKeyPair().getPublic(), COSEAlgorithmIdentifier.ES256);
    assertThat(key.getAlgorithm()).isEqualTo(COSEAlgorithmIdentifier.ES256);
    key = EC2COSEKey.create(ECUtil.createKeyPair(), COSEAlgorithmIdentifier.ES256);
    assertThat(key.getAlgorithm()).isEqualTo(COSEAlgorithmIdentifier.ES256);
}
 
示例11
@Override
public AttestationStatement createAttestationStatement(AttestationStatementRequest attestationStatementRequest, RegistrationEmulationOption registrationEmulationOption) {
    byte[] signature;
    if (registrationEmulationOption.isSignatureOverrideEnabled()) {
        signature = registrationEmulationOption.getSignature();
    } else {
        signature = TestDataUtil.calculateSignature(attestationStatementRequest.getCredentialKeyPair().getPrivate(), attestationStatementRequest.getSignedData());
    }
    AttestationOption attestationOption = registrationEmulationOption.getAttestationOption() == null ? new AndroidKeyAttestationOption() : registrationEmulationOption.getAttestationOption();
    X509Certificate attestationCertificate =
            getAttestationCertificate(attestationStatementRequest, attestationOption);

    AttestationCertificatePath attestationCertificates = new AttestationCertificatePath(attestationCertificate, this.getCACertificatePath());
    return new AndroidKeyAttestationStatement(COSEAlgorithmIdentifier.ES256, signature, attestationCertificates);
}
 
示例12
@Override
public AttestationStatement createAttestationStatement(AttestationStatementRequest attestationStatementRequest, RegistrationEmulationOption registrationEmulationOption) {
    byte[] signature;
    if (registrationEmulationOption.isSignatureOverrideEnabled()) {
        signature = registrationEmulationOption.getSignature();
    } else {
        signature = TestDataUtil.calculateSignature(this.getAttestationKeyPair().getPrivate(), attestationStatementRequest.getSignedData());
    }

    AttestationOption attestationOption = registrationEmulationOption.getAttestationOption() == null ? new PackedAttestationOption() : registrationEmulationOption.getAttestationOption();
    X509Certificate attestationCertificate = getAttestationCertificate(attestationStatementRequest, attestationOption);
    AttestationCertificatePath attestationCertificatePath = new AttestationCertificatePath(attestationCertificate, this.getCACertificatePath());
    return new PackedAttestationStatement(COSEAlgorithmIdentifier.ES256, signature, attestationCertificatePath);
}
 
示例13
public static AttestationObject createAttestationObjectWithSelfPackedECAttestationStatement(byte[] clientDataHash) {
    KeyPair keyPair = ECUtil.createKeyPair();
    EC2COSEKey ec2CredentialPublicKey = EC2COSEKey.create((ECPublicKey) keyPair.getPublic(), COSEAlgorithmIdentifier.ES256);
    AuthenticatorData<RegistrationExtensionAuthenticatorOutput<?>> authenticatorData = createAuthenticatorData(ec2CredentialPublicKey);
    byte[] authenticatorDataBytes = authenticatorDataConverter.convert(authenticatorData);
    byte[] signedData = createSignedData(authenticatorDataBytes, clientDataHash);
    byte[] signature = calculateSignature(keyPair.getPrivate(), signedData);
    return new AttestationObject(authenticatorData, TestAttestationStatementUtil.createSelfPackedAttestationStatement(COSEAlgorithmIdentifier.ES256, signature));
}
 
示例14
public static AttestationObject createAttestationObjectWithSelfPackedRSAAttestationStatement(byte[] clientDataHash) {
    KeyPair keyPair = RSAUtil.createKeyPair();
    RSACOSEKey rsaCredentialPublicKey = RSACOSEKey.create((RSAPublicKey) keyPair.getPublic(), COSEAlgorithmIdentifier.RS256);
    AuthenticatorData<RegistrationExtensionAuthenticatorOutput<?>> authenticatorData = createAuthenticatorData(rsaCredentialPublicKey);
    byte[] authenticatorDataBytes = authenticatorDataConverter.convert(authenticatorData);
    byte[] signedData = createSignedData(authenticatorDataBytes, clientDataHash);
    byte[] signature = calculateSignature(keyPair.getPrivate(), signedData);
    return new AttestationObject(authenticatorData, TestAttestationStatementUtil.createSelfPackedAttestationStatement(COSEAlgorithmIdentifier.RS256, signature));
}
 
示例15
public static EC2COSEKey createEC2COSEPublicKey() {
    return new EC2COSEKey(
            null,
            COSEAlgorithmIdentifier.ES256,
            null,
            Curve.SECP256R1,
            new byte[32],
            new byte[32]
    );
}
 
示例16
public static RSACOSEKey createRSACOSEPublicKey() {
    RSACOSEKey credentialPublicKey;
    credentialPublicKey = new RSACOSEKey(
            null,
            COSEAlgorithmIdentifier.RS256,
            null,
            new byte[32],
            new byte[32]
    );
    return credentialPublicKey;
}
 
示例17
/**
 * createEC2COSEPublicKey from {@code ECPublicKey}
 *
 * @param publicKey publicKey
 * @return {@link EC2COSEKey}
 */
public static EC2COSEKey createEC2COSEPublicKey(ECPublicKey publicKey) {
    ECPoint ecPoint = publicKey.getW();
    EllipticCurve ellipticCurve = publicKey.getParams().getCurve();
    Curve curve;
    COSEAlgorithmIdentifier coseAlgorithmIdentifier;

    switch (ellipticCurve.getField().getFieldSize()) {
        case 256:
            curve = Curve.SECP256R1;
            coseAlgorithmIdentifier = COSEAlgorithmIdentifier.ES256;
            break;
        case 384:
            curve = Curve.SECP384R1;
            coseAlgorithmIdentifier = COSEAlgorithmIdentifier.ES384;
            break;
        case 521:
            curve = Curve.SECP521R1;
            coseAlgorithmIdentifier = COSEAlgorithmIdentifier.ES512;
            break;
        default:
            throw new IllegalStateException("We can only support secp256r1, secp384r1 or secp521r1");
    }

    byte[] x = ECUtil.convertToFixedByteArray(curve.getSize(), ecPoint.getAffineX());
    byte[] y = ECUtil.convertToFixedByteArray(curve.getSize(), ecPoint.getAffineY());
    return new EC2COSEKey(
            null,
            coseAlgorithmIdentifier,
            null,
            curve,
            x,
            y
    );
}
 
示例18
protected String getJcaName(COSEAlgorithmIdentifier alg) {
    String jcaName;
    try {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.create(alg);
        jcaName = signatureAlgorithm.getJcaName();
    } catch (IllegalArgumentException e) {
        throw new BadAttestationStatementException("alg is not signature algorithm", e);
    }
    return jcaName;
}
 
示例19
private AttestationType validateSelfAttestation(RegistrationObject registrationObject, byte[] sig, COSEAlgorithmIdentifier alg, byte[] attrToBeSigned) {
    COSEKey coseKey =
            registrationObject.getAttestationObject().getAuthenticatorData().getAttestedCredentialData().getCOSEKey();
    // Validate that alg matches the algorithm of the coseKey in authenticatorData.
    COSEAlgorithmIdentifier credentialPublicKeyAlgorithm = coseKey.getAlgorithm();
    if (!alg.equals(credentialPublicKeyAlgorithm)) {
        throw new BadAlgorithmException("`alg` in attestation statement doesn't match the algorithm of the coseKey in authenticatorData.");
    }
    // Verify that sig is a valid signature over the concatenation of authenticatorData and clientDataHash using the credential public key with alg.
    if (!verifySignature(coseKey.getPublicKey(), alg, sig, attrToBeSigned)) {
        throw new BadSignatureException("`sig` in attestation statement is not valid signature over the concatenation of authenticatorData and clientDataHash.");
    }
    // If successful, return attestation type Self and empty attestation trust path.
    return AttestationType.SELF;
}
 
示例20
private boolean verifySignature(PublicKey publicKey, COSEAlgorithmIdentifier algorithmIdentifier, byte[] signature, byte[] data) {
    try {
        String jcaName = getJcaName(algorithmIdentifier);
        Signature verifier = SignatureUtil.createSignature(jcaName);
        verifier.initVerify(publicKey);
        verifier.update(data);

        return verifier.verify(signature);
    } catch (SignatureException | InvalidKeyException | RuntimeException e) {
        return false;
    }
}
 
示例21
@JsonCreator
public PublicKeyCredentialParameters(
        @JsonProperty("type") PublicKeyCredentialType type,
        @JsonProperty("alg") COSEAlgorithmIdentifier alg) {
    this.type = type;
    this.alg = alg;
}
 
示例22
@JsonCreator
AbstractCOSEKey(
        @JsonProperty("2") byte[] keyId,
        @JsonProperty("3") COSEAlgorithmIdentifier algorithm,
        @JsonProperty("4") List<COSEKeyOperation> keyOps,
        @JsonProperty("5") byte[] baseIV
) {
    this.keyId = keyId;
    this.algorithm = algorithm;
    this.keyOps = keyOps;
    this.baseIV = baseIV;
}
 
示例23
/**
 * Constructor for public key
 *
 * @param keyId     keyId
 * @param algorithm algorithm
 * @param keyOps    keyOps
 * @param curve     curve
 * @param x         x
 * @param y         y
 */
@SuppressWarnings("squid:S00107")
public EC2COSEKey(
        @JsonProperty("2") byte[] keyId,
        @JsonProperty("3") COSEAlgorithmIdentifier algorithm,
        @JsonProperty("4") List<COSEKeyOperation> keyOps,
        @JsonProperty("-1") Curve curve,
        @JsonProperty("-2") byte[] x,
        @JsonProperty("-3") byte[] y) {
    super(keyId, algorithm, keyOps, null);
    this.curve = curve;
    this.x = x;
    this.y = y;
}
 
示例24
public static EC2COSEKey create(ECPublicKey publicKey, COSEAlgorithmIdentifier alg) {
    ECPoint ecPoint = publicKey.getW();
    Curve curve = getCurve(publicKey.getParams());
    byte[] x = ECUtil.convertToFixedByteArray(curve.getSize(), ecPoint.getAffineX());
    byte[] y = ECUtil.convertToFixedByteArray(curve.getSize(), ecPoint.getAffineY());
    return new EC2COSEKey(null, alg, null, curve, x, y);
}
 
示例25
public static EC2COSEKey create(KeyPair keyPair, COSEAlgorithmIdentifier alg) {
    if (keyPair != null && keyPair.getPrivate() instanceof ECPrivateKey && keyPair.getPublic() instanceof ECPublicKey) {
        ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
        ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
        ECPoint ecPoint = ecPublicKey.getW();
        Curve curve = getCurve(ecPrivateKey.getParams());
        byte[] x = ECUtil.convertToFixedByteArray(curve.getSize(), ecPoint.getAffineX());
        byte[] y = ECUtil.convertToFixedByteArray(curve.getSize(), ecPoint.getAffineY());
        byte[] d = ecPrivateKey.getS().toByteArray();
        return new EC2COSEKey(null, alg, null, curve, x, y, d);
    } else {
        throw new IllegalArgumentException();
    }
}
 
示例26
/**
 * Constructor for public key
 *
 * @param keyId     keyId
 * @param algorithm algorithm
 * @param keyOps    keyOps
 * @param curve     curve
 * @param d         d
 */
@SuppressWarnings("squid:S00107")
public EC2COSEKey(
        @JsonProperty("2") byte[] keyId,
        @JsonProperty("3") COSEAlgorithmIdentifier algorithm,
        @JsonProperty("4") List<COSEKeyOperation> keyOps,
        @JsonProperty("-1") Curve curve,
        @JsonProperty("-2") byte[] d) {
    super(keyId, algorithm, keyOps, null);
    this.curve = curve;
    this.d = d;
}
 
示例27
/**
 * Constructor for public key
 *
 * @param keyId     keyId
 * @param algorithm algorithm
 * @param keyOps    keyOps
 * @param n         n
 * @param e         e
 */
@SuppressWarnings("squid:S00107")
public RSACOSEKey(
        @JsonProperty("2") byte[] keyId,
        @JsonProperty("3") COSEAlgorithmIdentifier algorithm,
        @JsonProperty("4") List<COSEKeyOperation> keyOps,
        @JsonProperty("-1") byte[] n,
        @JsonProperty("-2") byte[] e) {
    super(keyId, algorithm, keyOps, null);
    this.n = n;
    this.e = e;
}
 
示例28
public static RSACOSEKey create(KeyPair keyPair, COSEAlgorithmIdentifier alg) {
    if(keyPair != null && keyPair.getPrivate() instanceof RSAPrivateKey && keyPair.getPublic() instanceof RSAPublicKey){
        RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();

        byte[] n = rsaPublicKey.getModulus().toByteArray();
        byte[] e = rsaPublicKey.getPublicExponent().toByteArray();
        byte[] d = rsaPrivateKey.getPrivateExponent().toByteArray();
        return new RSACOSEKey(null, alg, null, n, e, d, null, null, null, null, null);
    }
    else {
        throw new IllegalArgumentException();
    }
}
 
示例29
private AttestationObject createAttestationObject(String rpId, Challenge challenge) {
    AuthenticatorSelectionCriteria authenticatorSelectionCriteria =
            new AuthenticatorSelectionCriteria(
                    AuthenticatorAttachment.CROSS_PLATFORM,
                    true,
                    UserVerificationRequirement.REQUIRED);

    PublicKeyCredentialParameters publicKeyCredentialParameters = new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256);

    PublicKeyCredentialUserEntity publicKeyCredentialUserEntity = new PublicKeyCredentialUserEntity();

    AuthenticationExtensionsClientInputs<RegistrationExtensionClientInput<?>> extensions = new AuthenticationExtensionsClientInputs<>();
    PublicKeyCredentialCreationOptions credentialCreationOptions
            = new PublicKeyCredentialCreationOptions(
            new PublicKeyCredentialRpEntity(rpId, "example.com"),
            publicKeyCredentialUserEntity,
            challenge,
            Collections.singletonList(publicKeyCredentialParameters),
            null,
            Collections.emptyList(),
            authenticatorSelectionCriteria,
            AttestationConveyancePreference.NONE,
            extensions
    );

    AuthenticatorAttestationResponse registrationRequest = clientPlatform.create(credentialCreationOptions).getAuthenticatorResponse();
    AttestationObjectConverter attestationObjectConverter = new AttestationObjectConverter(objectConverter);
    return attestationObjectConverter.convert(registrationRequest.getAttestationObject());
}
 
示例30
private AttestationObject createAttestationObject(String rpId, Challenge challenge) {
    PublicKeyCredentialParameters publicKeyCredentialParameters
            = new PublicKeyCredentialParameters(PublicKeyCredentialType.PUBLIC_KEY, COSEAlgorithmIdentifier.ES256);

    PublicKeyCredentialCreationOptions credentialCreationOptions = new PublicKeyCredentialCreationOptions(
            new PublicKeyCredentialRpEntity(rpId, "example.com"),
            new PublicKeyCredentialUserEntity(),
            challenge,
            Collections.singletonList(publicKeyCredentialParameters)
    );
    AuthenticatorAttestationResponse registrationRequest = clientPlatform.create(credentialCreationOptions).getAuthenticatorResponse();
    AttestationObjectConverter attestationObjectConverter = new AttestationObjectConverter(objectConverter);
    return attestationObjectConverter.convert(registrationRequest.getAttestationObject());
}