mirror of
https://github.com/cryptomator/cryptomator.git
synced 2024-11-23 12:09:45 +00:00
add new API encryptVaultKey(vaultKey, userKey)
and `decodeECPublicKey(byte[])`
This commit is contained in:
parent
e9ee17493b
commit
2e443c72a9
@ -24,6 +24,7 @@ import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
@ -92,6 +93,42 @@ class JWEHelper {
|
||||
throw new KeyDecodeFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to decode a DER-encoded EC public key.
|
||||
*
|
||||
* @param encoded DER-encoded EC public key
|
||||
* @return the decoded key
|
||||
* @throws KeyDecodeFailedException On malformed input
|
||||
*/
|
||||
public static ECPublicKey decodeECPublicKey(byte[] encoded) throws KeyDecodeFailedException {
|
||||
try {
|
||||
KeyFactory factory = KeyFactory.getInstance(EC_ALG);
|
||||
var publicKey = factory.generatePublic(new X509EncodedKeySpec(encoded));
|
||||
if (publicKey instanceof ECPublicKey ecPublicKey) {
|
||||
return ecPublicKey;
|
||||
} else {
|
||||
throw new IllegalStateException(EC_ALG + " key factory not generating ECPublicKeys");
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new IllegalStateException(EC_ALG + " not supported");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new KeyDecodeFailedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static JWEObject encryptVaultKey(Masterkey vaultKey, ECPublicKey userKey) {
|
||||
try {
|
||||
var encodedVaultKey = Base64.getEncoder().encodeToString(vaultKey.getEncoded());
|
||||
var keyGen = new ECKeyGenerator(Curve.P_384);
|
||||
var ephemeralKeyPair = keyGen.generate();
|
||||
var header = new JWEHeader.Builder(JWEAlgorithm.ECDH_ES, EncryptionMethod.A256GCM).ephemeralPublicKey(ephemeralKeyPair.toPublicJWK()).build();
|
||||
var payload = new Payload(Map.of(JWE_PAYLOAD_KEY_FIELD, encodedVaultKey));
|
||||
var jwe = new JWEObject(header, payload);
|
||||
jwe.encrypt(new ECDHEncrypter(userKey));
|
||||
return jwe;
|
||||
} catch (JOSEException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.cryptomator.ui.keyloading.hub;
|
||||
|
||||
import com.nimbusds.jose.JWEObject;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
|
||||
import org.cryptomator.cryptolib.common.P384KeyPair;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@ -140,4 +141,31 @@ public class JWEHelperTest {
|
||||
Assertions.assertThrows(MasterkeyLoadingFailedException.class, () -> JWEHelper.decryptVaultKey(jwe, privateKey));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("decrypt(encrypt(vaultKey, userPublicKey), userPrivateKey) == vaultKey")
|
||||
public void testEncryptAndDecryptVaultKey() {
|
||||
var keyBytes = new byte[64];
|
||||
Arrays.fill(keyBytes, 0, 32, (byte) 0x55);
|
||||
Arrays.fill(keyBytes, 32, 64, (byte) 0x77);
|
||||
var vaultKey = new Masterkey(keyBytes);
|
||||
var userKey = P384KeyPair.generate();
|
||||
|
||||
var encrypted = JWEHelper.encryptVaultKey(vaultKey, userKey.getPublic());
|
||||
var decrypted = JWEHelper.decryptVaultKey(encrypted, userKey.getPrivate());
|
||||
|
||||
Assertions.assertArrayEquals(keyBytes, decrypted.getEncoded());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("decrypt(encrypt(userKey, devicePublicKey), devicePrivateKey) == userKey")
|
||||
public void testEncryptAndDecryptUserKey() {
|
||||
var userKey = P384KeyPair.generate();
|
||||
var deviceKey = P384KeyPair.generate();
|
||||
|
||||
var encrypted = JWEHelper.encryptUserKey(userKey.getPrivate(), deviceKey.getPublic());
|
||||
var decrypted = JWEHelper.decryptUserKey(encrypted, deviceKey.getPrivate());
|
||||
|
||||
Assertions.assertArrayEquals(userKey.getPrivate().getEncoded(), decrypted.getEncoded());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user