Как мне сгенерировать JWT из секретного ключа, который был создан с использованием «PBKDF2withHmacSHA256» в Android? - PullRequest
1 голос
/ 24 сентября 2019

Поэтому я пытаюсь сгенерировать токен JWT из моего ключа, сгенерированного с использованием PBKDF2 , и код выглядит так в Android:

public SecretKey generateKey(String passphraseOrPin) throws NoSuchAlgorithmException, InvalidKeySpecException {

        final int iterations = 5000;

        // Generate a 256-bit key
        final int outputKeyLength = 256;
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2withHmacSHA256");
        KeySpec keySpec = new PBEKeySpec(getSha256Hash(passphraseOrPin).toCharArray(), salt.getBytes(), iterations, outputKeyLength);
        SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);

        return secretKey;
    }

Но всякий раз, когда япытаюсь сгенерировать токен:

String jwtString = Jwts.builder().setSubject("sub").signWith(key, SignatureAlgorithm.HS256).compact();

получаю ошибку:

Process: com.android.gocontract, PID: 7434
    java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.
        at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:111)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: io.jsonwebtoken.security.InvalidKeyException: The signing key's algorithm 'PBKDF2WithHmacSHA256' does not equal a valid HmacSHA* algorithm name and cannot be used with HS256.
        at io.jsonwebtoken.SignatureAlgorithm.assertValid(SignatureAlgorithm.java:358)
        at io.jsonwebtoken.SignatureAlgorithm.assertValidSigningKey(SignatureAlgorithm.java:302)
        at io.jsonwebtoken.impl.DefaultJwtBuilder.signWith(DefaultJwtBuilder.java:123)
        at com.android.gocontract.Activity.LoginActivity$2.onNext(LoginActivity.java:192)
        at com.android.gocontract.Activity.LoginActivity$2.onNext(LoginActivity.java:163)
        at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:200)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:252)
        at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:109)
        at android.os.Handler.handleCallback(Handler.java:873) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
2019-09-23 18:38:37.036 7434-7434/com.android.gocontract I/Process: Sending signal. PID: 7434 SIG: 9

метод генерации Sha256:

public String getSha256Hash(String password) {
        try {
            MessageDigest digest = null;
            try {
                digest = MessageDigest.getInstance("SHA-256");
            } catch (NoSuchAlgorithmException e1) {
                e1.printStackTrace();
            }
            digest.reset();
            return bin2hex(digest.digest(password.getBytes()));
        } catch (Exception ignored) {
            return null;
        }
    }

версия jjwt :

 api 'io.jsonwebtoken:jjwt-api:0.10.7'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.10.7'
    runtimeOnly('io.jsonwebtoken:jjwt-orgjson:0.10.7') {
        exclude group: 'org.json', module: 'json' //provided by Android natively
    }

1 Ответ

1 голос
/ 25 сентября 2019

Решение: использовать другой алгоритм шифрования или использовать lib Spongy Castle .

Полезная lib: Nimbus JOSE JWT Spongycastle ,если вам нужна помощь в смешивании jwt с губчатым замком.

Почему это не работает для вас: это особенность используемого вами устройства.Некоторые устройства поддерживают алгоритм PBKDF2withHmacSHA256, а другие - нет.

Как я пришел к такому выводу: Сначала я подумал, что это может быть простая опечатка, но я нашел в JJWT github, что, хотя проблема действительно существовала, она уже была исправлена.Поскольку проверка теперь использует equalsignorecase, опечатка не будет иметь значения.Вы можете подтвердить в код .

Тогда я подумал, что это может быть версия для Android или Java.Но я обнаружил, что с момента выпуска java 8 он уже реализован.

Я думал, что это может быть версия для Android, но он работает с API 26 .

Я также протестировал код, который вы используете, и он работал отлично, поэтому никаких проблем не возникнет.Затем я много исследовал, видел некоторые другие вопросы , люди, имеющие такую ​​же проблему с другими библиотеками и другими алгоритмами .

Дополнительно: Существует код от k3v , который, вероятно, может помочь вам (используя Spongy Castle):

PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
generator.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password), salt, iterations); 
KeyParameter key = (KeyParameter)generator.generateDerivedMacParameters(keySizeInBits);
...