bloxbean / cardano-client-lib

Cardano client library in Java
https://cardano-client.dev
MIT License
118 stars 49 forks source link

[Android] Mnemonic to KeyPair generation failed #82

Closed JaimeToca closed 2 years ago

JaimeToca commented 2 years ago

Issue description Hello everyone ! I have added v0.2.0-beta2 to a test project in Android (java 11), but when I try to create a new account I get the following crash with the stracktrace:

com.bloxbean.cardano.client.crypto.CryptoException: Mnemonic to KeyPair generation failed at com.bloxbean.cardano.client.crypto.cip1852.CIP1852.getKeyPairFromMnemonic(CIP1852.java:16) at com.bloxbean.cardano.client.account.Account.getHdKeyPair(Account.java:379) at com.bloxbean.cardano.client.account.Account.baseAddress(Account.java:191) at com.bloxbean.cardano.client.account.Account.generateNew(Account.java:355) at com.bloxbean.cardano.client.account.Account.<init>(Account.java:85) at com.bloxbean.cardano.client.account.Account.<init>(Account.java:73) at com.bloxbean.cardano.client.account.Account.<init>(Account.java:63)

.....

Caused by: java.security.spec.InvalidKeySpecException: Could not generate secret key at javax.crypto.SecretKeyFactory.generateSecret(SecretKeyFactory.java:531) at com.bloxbean.cardano.client.crypto.bip32.HdKeyGenerator.pbkdf2HmacSha512(HdKeyGenerator.java:76) at com.bloxbean.cardano.client.crypto.bip32.HdKeyGenerator.getRootKeyPairFromEntropy(HdKeyGenerator.java:33)  at com.bloxbean.cardano.client.crypto.cip1852.CIP1852.getKeyPairFromEntropy(CIP1852.java:22)  at com.bloxbean.cardano.client.crypto.cip1852.CIP1852.getKeyPairFromMnemonic(CIP1852.java:14)  at com.bloxbean.cardano.client.account.Account.getHdKeyPair(Account.java:379)  at com.bloxbean.cardano.client.account.Account.baseAddress(Account.java:191)  at com.bloxbean.cardano.client.account.Account.generateNew(Account.java:355)  at com.bloxbean.cardano.client.account.Account.<init>(Account.java:85)  at com.bloxbean.cardano.client.account.Account.<init>(Account.java:73)  at com.bloxbean.cardano.client.account.Account.<init>(Account.java:63) 

....

Caused by: java.lang.IllegalArgumentException: password empty at com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$BasePBKDF2.engineGenerateSecret(PBEPBKDF2.java:202) at javax.crypto.SecretKeyFactory.generateSecret(SecretKeyFactory.java:520) at com.bloxbean.cardano.client.crypto.bip32.HdKeyGenerator.pbkdf2HmacSha512(HdKeyGenerator.java:76)  at com.bloxbean.cardano.client.crypto.bip32.HdKeyGenerator.getRootKeyPairFromEntropy(HdKeyGenerator.java:33)  at com.bloxbean.cardano.client.crypto.cip1852.CIP1852.getKeyPairFromEntropy(CIP1852.java:22)  at com.bloxbean.cardano.client.crypto.cip1852.CIP1852.getKeyPairFromMnemonic(CIP1852.java:14)  at com.bloxbean.cardano.client.account.Account.getHdKeyPair(Account.java:379)  at com.bloxbean.cardano.client.account.Account.baseAddress(Account.java:191)  at com.bloxbean.cardano.client.account.Account.generateNew(Account.java:355)  at com.bloxbean.cardano.client.account.Account.<init>(Account.java:85)  at com.bloxbean.cardano.client.account.Account.<init>(Account.java:73)  at com.bloxbean.cardano.client.account.Account.<init>(Account.java:63)  at com.agile.wallet.MainActivity.onCreate$lambda-0(MainActivity.kt:53) 

As you can see: mnemonic 24 word is generated properly with the call mnemonic = MnemonicCode.INSTANCE.createMnemonic(noOfWords).stream().collect(Collectors.joining(" ")); After that baseAddress() is called and then getHdKeyPair() . This is where it crashes, if you follow the logs it seems that PBEPBKDF2.java throws IllegalArgumentException("password empty"); It was a very simple call Account account = new Account();

Perhaps I am missing something that needs to be added to my project???

Cheers

satran004 commented 2 years ago

@JaimeToca Thanks for reporting this.

I have to admit, I had not tested v0.2.0-beta2 with Android :(

But I tried a sample app and I am able to reproduce this error. As you mentioned, the exception is thrown from Android's PBKDF2WithHmacSHA512 hash implementation. If I am not wrong, it's due to empty password in our case

I am checking for alternatives to fix this issue.

satran004 commented 2 years ago

@JaimeToca One option is to directly use bouncycastle class in case of Android.

I replaced the current impl of pbkdf2HmacSha512 method in HdKeyGenerator.java with the following. It seems to be working. I tried from account generation to transaction posting in a sample android app and it worked.

For now, you may want to build cardano-client-lib locally with the following change and push to local maven repo to try.

private byte[] pbkdf2HmacSha512(final char[] password, final byte[] salt, final int iterations,
                                    final int keyLength) {
        try {
            PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA512Digest());
            gen.init(new String(password).getBytes(StandardCharsets.UTF_8), salt, iterations);
            byte[] dk = ((KeyParameter) gen.generateDerivedParameters(keyLength)).getKey();

            return dk;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

I/System.out: Result{successful=true, response='Response{protocol=h2, code=200, message=, url=https://cardano-testnet.blockfrost.io/api/v0/tx/submit}', code=200, value=d96afcb1787671e17add9cc014b15bf8eb0663857ceae4545315f9f75b4bbd5b} I/System.out: Transaction Id: d96afcb1787671e17add9cc014b15bf8eb0663857ceae4545315f9f75b4bbd5b

JaimeToca commented 2 years ago

Hey @satran004 no problem !! Thanks a lot for your time and effort !! I'm super excited about this library 🚀 🚀 🚀 . I'll replace the current impl of pbkdf2HmacSha512 and add the one you post it as a temporary solution.

Thanks again ! Cheers

satran004 commented 2 years ago

@JaimeToca Fyi, you can now use the latest snapshot version if don't want to build locally. https://github.com/bloxbean/cardano-client-lib#for-snapshot-binary

Feel free to report if you find any other Android specific issue. Goal is to make this library Android compatible :)

JaimeToca commented 2 years ago

Awesome @satran004. I'll check it out during this week. Keep up the good work !

P.D: I do have plans to build something pretty cool with this lib ;)

edridudi commented 2 years ago

@JaimeToca Can we Close this issue?

JaimeToca commented 2 years ago

Hello @edridudi . srry, yes this issue can be closed :)