Update EncryptedMultisigDescriptor.java

Replaced broken code relying on non-existent Java methods (getAuthenticationTag() and setAuthenticationTag()), causing compilation errors.
Correctly implemented AES-GCM encryption and decryption:
Removed manual extraction/injection of authentication tags.
Encrypted blobs now properly combine IV and ciphertext (with embedded tag).
Decryption validates integrity via Cipher.doFinal().
Ensured secure key derivation using SHA-256 on sorted zpubs.
This commit is contained in:
PeterMcBTC 2025-07-14 11:26:02 +02:00 committed by GitHub
parent d8b3672711
commit 7fae9d7d5f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -34,26 +34,28 @@ public class EncryptedMultisigDescriptor {
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH * 8, iv); // Create GCM spec with IV and tag bits
cipher.init(Cipher.ENCRYPT_MODE, skey, spec); // Initialize cipher for encryption
byte[] ct = cipher.doFinal(descriptor.getBytes(StandardCharsets.UTF_8)); // Encrypt descriptor to ciphertext
byte[] tag = cipher.getAuthenticationTag(); // Get authentication tag (unused here, but typically from doFinal)
byte[] blob = new byte[IV_LENGTH + TAG_LENGTH + ct.length]; // Create output blob array
// Build encryption blob: IV + Ciphertext (tag included in ciphertext)
byte[] blob = new byte[IV_LENGTH + ct.length]; // IV + Ciphertext (which includes tag)
System.arraycopy(iv, 0, blob, 0, IV_LENGTH); // Copy IV to start of blob
System.arraycopy(tag, 0, blob, IV_LENGTH, TAG_LENGTH); // Copy tag after IV
System.arraycopy(ct, 0, blob, IV_LENGTH + TAG_LENGTH, ct.length); // Copy ciphertext after tag
System.arraycopy(ct, 0, blob, IV_LENGTH, ct.length); // Copy entire ciphertext (tag included) after IV
return Base64.getEncoder().encodeToString(blob); // Base64 encode blob and return as string
}
// Method to decrypt an encrypted blob string using AES-GCM with the given key
public static String decrypt(String blobStr, byte[] key) throws Exception {
byte[] blob = Base64.getDecoder().decode(blobStr); // Decode Base64 blob to bytes
if (blob.length < IV_LENGTH + TAG_LENGTH) throw new IllegalArgumentException(); // Check minimum length
if (blob.length < IV_LENGTH) throw new IllegalArgumentException("Invalid blob length"); // Check minimum length
byte[] iv = Arrays.copyOfRange(blob, 0, IV_LENGTH); // Extract IV from blob
byte[] tag = Arrays.copyOfRange(blob, IV_LENGTH, IV_LENGTH + TAG_LENGTH); // Extract tag
byte[] ct = Arrays.copyOfRange(blob, IV_LENGTH + TAG_LENGTH, blob.length); // Extract ciphertext
byte[] ct = Arrays.copyOfRange(blob, IV_LENGTH, blob.length); // Extract ciphertext (tag included)
SecretKeySpec skey = new SecretKeySpec(key, "AES"); // Create AES key
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); // Get cipher instance
GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH * 8, iv); // Create GCM spec
cipher.init(Cipher.DECRYPT_MODE, skey, spec); // Initialize for decryption
cipher.setAuthenticationTag(tag); // Set expected tag for verification (GCM-specific)
try {
return new String(cipher.doFinal(ct), StandardCharsets.UTF_8); // Decrypt and return string
} catch (AEADBadTagException e) {