nostr-java
nostr-java copied to clipboard
NIP44 encrypt/decrypt doesn't work unless Schnorr#generatePrivateKey() is called first
Without bouncycastle as a security provider you get a runtime exception when trying to encrypt/decrypt:
Execution error (InvalidAlgorithmParameterException) at com.sun.crypto.provider.ChaCha20Cipher/engineInit (ChaCha20Cipher.java:335).
ChaCha20 algorithm requires ChaCha20ParameterSpec
The tests are passing because
Schnorr#generatePrivateKey() calls Security.addProvider(new BouncyCastleProvider());
Either the provider needs to be added some other way or the implementation of EncryptedPayloads need to excplicitly use ChaCha20ParameterSpec:
diff --git a/nostr-java-crypto/src/main/java/nostr/crypto/nip44/EncryptedPayloads.java b/nostr-java-crypto/src/main/java/nostr/crypto/nip44/EncryptedPayloads.java
index 8d05d3ca..a345efb6 100644
--- a/nostr-java-crypto/src/main/java/nostr/crypto/nip44/EncryptedPayloads.java
+++ b/nostr-java-crypto/src/main/java/nostr/crypto/nip44/EncryptedPayloads.java
@@ -3,6 +3,7 @@ package nostr.crypto.nip44;
import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.ChaCha20ParameterSpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
@@ -39,13 +40,13 @@ public class EncryptedPayloads {
byte[] chachaNonce = keys[1];
byte[] hmacKey = keys[2];
- byte[] padded = EncryptedPayloads.pad(plaintext);
+ byte[] padded = EncryptedPayloads.pad(plaintext);
Cipher cipher = Cipher.getInstance(Constants.ENCRYPTION_ALGORITHM);
cipher.init(
Cipher.ENCRYPT_MODE,
new SecretKeySpec(chachaKey, Constants.ENCRYPTION_ALGORITHM),
- new IvParameterSpec(chachaNonce));
+ new ChaCha20ParameterSpec(chachaNonce, 0));
byte[] ciphertext = cipher.doFinal(padded);
Mac mac = Mac.getInstance(Constants.HMAC_ALGORITHM);
@@ -92,7 +93,7 @@ public class EncryptedPayloads {
cipher.init(
Cipher.DECRYPT_MODE,
new SecretKeySpec(chachaKey, Constants.ENCRYPTION_ALGORITHM),
- new IvParameterSpec(chachaNonce));
+ new ChaCha20ParameterSpec(chachaNonce, 0));
byte[] paddedPlaintext = cipher.doFinal(ciphertext);
return EncryptedPayloads.unpad(paddedPlaintext);