Статус: Новичок
Группы: Участники
Зарегистрирован: 31.07.2020(UTC) Сообщений: 9
|
Добрый день. В debug режиме все работает как часы. Собрал релизную сборку и тестирую на телефоне, криптопровайдер вызывает краш всего приложения, предположительно на вызове Security.addProvider(new JCSP()) Версия CSP - 4.0 minSdkVersion 24 Gradle 6.7 В androidManifest прописано <application android:extractNativeLibs="true"></application> В gradle.properties android.bundle.enableUncompressedNativeLibs = false Тестирую релизную сборку на телефоне с Android 11 build.gradle
buildscript { repositories { google() jcenter() }
dependencies { classpath 'com.android.tools.build:gradle:4.1.0' } }
rootProject.allprojects { repositories { google() jcenter() } }
apply plugin: 'com.android.library'
android { compileSdkVersion 30
lintOptions { disable 'InvalidPackage' }
defaultConfig { minSdkVersion 24 }
dexOptions { preDexLibraries = false javaMaxHeapSize "4g" additionalParameters =["--core-library"] }
packagingOptions { exclude 'META-INF/Digest.CP' exclude 'META-INF/Sign.CP' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/LICENSE.txt' doNotStrip "*/arm64-v8a/*.so" doNotStrip "*/armeabi/*.so" doNotStrip "*/x86_64/*.so" doNotStrip "*/x86/*.so" }
lintOptions { abortOnError false } }
dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation group: 'commons-io', name: 'commons-io', version: '2.5' implementation group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1' implementation 'org.apache.httpcomponents:httpclient:4.2.1' implementation 'androidx.annotation:annotation:1.1.0' }
Ошибка
[+2380 ms] E/AndroidRuntime(30222): FATAL EXCEPTION: main [ ] E/AndroidRuntime(30222): Process: com.example.example, PID: 30222 [ ] E/AndroidRuntime(30222): java.lang.ExceptionInInitializerError [ ] E/AndroidRuntime(30222): at ru.CryptoPro.JCSP.MSCAPI.CAPI.cryptEnumProviders(Native Method) [ ] E/AndroidRuntime(30222): at ru.CryptoPro.JCSP.MSCAPI.t.a(Unknown Source:73) [ ] E/AndroidRuntime(30222): at ru.CryptoPro.JCSP.MSCAPI.t.x(Unknown Source:18) [ ] E/AndroidRuntime(30222): at f.a.c.o.a.e(Unknown Source:0) [ ] E/AndroidRuntime(30222): at f.a.c.o.a.b(Unknown Source:0) [ ] E/AndroidRuntime(30222): at f.a.c.o.b.run(Unknown Source:11) [ ] E/AndroidRuntime(30222): at java.security.AccessController.doPrivileged(AccessController.java:43) [ ] E/AndroidRuntime(30222): at f.a.c.o.a.c(Unknown Source:5) [ ] E/AndroidRuntime(30222): at f.a.c.o.a.<clinit>(Unknown Source:17) [ ] E/AndroidRuntime(30222): at f.a.c.o.a.k(Unknown Source:0) [ ] E/AndroidRuntime(30222): at ru.CryptoPro.JCSP.MSCAPI.d.<clinit>(Unknown Source:0) [ ] E/AndroidRuntime(30222): at f.a.c.f.D(Unknown Source:0) [ ] E/AndroidRuntime(30222): at f.a.c.f.y(Unknown Source:63) [ +1 ms] E/AndroidRuntime(30222): at f.a.c.f.<init>(Unknown Source:18) [ +1 ms] E/AndroidRuntime(30222): at f.c.a.a.e(Unknown Source:25) [ ] E/AndroidRuntime(30222): at f.c.a.a.f(Unknown Source:58) [ ] E/AndroidRuntime(30222): at d.a.c.a.j$a.a(Unknown Source:17) [ ] E/AndroidRuntime(30222): at io.flutter.embedding.engine.e.b.d(Unknown Source:57) [ ] E/AndroidRuntime(30222): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(Unknown Source:4) [ +1 ms] E/AndroidRuntime(30222): at android.os.MessageQueue.nativePollOnce(Native Method) [ ] E/AndroidRuntime(30222): at android.os.MessageQueue.next(MessageQueue.java:335) [ ] E/AndroidRuntime(30222): at android.os.Looper.loop(Looper.java:193) [ ] E/AndroidRuntime(30222): at android.app.ActivityThread.main(ActivityThread.java:8060) [ ] E/AndroidRuntime(30222): at java.lang.reflect.Method.invoke(Native Method) [ ] E/AndroidRuntime(30222): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656) [ ] E/AndroidRuntime(30222): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967) [ ] E/AndroidRuntime(30222): Caused by: java.lang.RuntimeException: java.lang.NoSuchFieldException: No field INSTANCE in class Lf/a/c/c; (declaration of 'f.a.c.c' appears in /data/app/~~SSD67cGD-zVbbVQaKoNuug==/com.example.example-TtmU6KhDXcT35VPQIMjbdA==/base.apk) [ +1 ms] E/AndroidRuntime(30222): at ru.CryptoPro.JCSP.MSCAPI.CAPI.b(Unknown Source:86) [ ] E/AndroidRuntime(30222): at ru.CryptoPro.JCSP.MSCAPI.CAPI.<clinit>(Unknown Source:17) [ ] E/AndroidRuntime(30222): ... 26 more [ ] E/AndroidRuntime(30222): Caused by: java.lang.NoSuchFieldException: No field INSTANCE in class Lf/a/c/c; (declaration of 'f.a.c.c' appears in /data/app/~~SSD67cGD-zVbbVQaKoNuug==/com.example.example-TtmU6KhDXcT35VPQIMjbdA==/base.apk) [ +1 ms] E/AndroidRuntime(30222): at java.lang.Class.getDeclaredField(Native Method) [ ] E/AndroidRuntime(30222): at ru.CryptoPro.JCSP.MSCAPI.CAPI.b(Unknown Source:8) [ ] E/AndroidRuntime(30222): ... 27 more
В чем может быть проблема? Спасибо
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,963 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 704 раз в 665 постах
|
Здравствуйте. Возможно, выполняется сильная обфускация кода в релизном приложении, в отличие от дебаг. Исключите из обфускации модули SDK. |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 31.07.2020(UTC) Сообщений: 9
|
Отключил обфускацию для конкретного класса, который ищется через рефлексию и провайдер инициализировался, спасибо! (-keep public class ru.CryptoPro.JCSP.CSPInternalConfig) Однако, возникла другая проблема. Запускаю один и тот же код под дебагом на эмуляторе и телефоне с одним и тем же .pfx контейнером. Ищу среди алисов контейнер с приватным ключом. На эмуляторе все прекрасно работает, но на телефоне alias остается null, т.к условие Код:if (keyStorePFX.isKeyEntry(aliasPFX))
не выполняется ни разу. В лог выводятся одинаковые алиасы (первый идет крипто про, потом мой) Если на телефоне убираю условие Код:if (keyStorePFX.isKeyEntry(aliasPFX))
и иду дальше на подписание, то появляется ошибка о том, что невозможно получить алгоритм приватного ключа
KeyStore keyStorePFX = KeyStore.getInstance(JCSP.PFX_STORE_NAME, JCSP.PROVIDER_NAME); InputStream fileInputStream = new FileInputStream(context.getFilesDir().getParent() + "s.pfx");
keyStorePFX.load(fileInputStream, password.toCharArray());
String alias = null; Enumeration<String> aliasesPFX = keyStorePFX.aliases();
while (aliasesPFX.hasMoreElements()) { String aliasPFX = aliasesPFX.nextElement(); log.info("aliasPFX" + aliasPFX); if (keyStorePFX.isKeyEntry(aliasPFX)) alias = aliasPFX; }
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,963 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 704 раз в 665 постах
|
В logcat есть какие-нибудь ошибки? Если явных ошибок нет, то включите логирование так: adb shell setprop log.tag.JCP VERBOSE и проверьте, есть ли теперь логи в logcat. Если нет, то попробуйте так: adb shell setprop log.tag.JCP DEBUG |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 31.07.2020(UTC) Сообщений: 9
|
Явных ошибок в логе не увидел. Ошибка, если без проверки на isKeyEntry выполнить Код:PrivateKey privateKey = (PrivateKey) keyStorePFX.getKey(alias, password.toCharArray());
signature.initSign(privateKey);
I/(11282): java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.security.PrivateKey.getAlgorithm()' on a null object reference I/(11282): at ru.CryptoPro.JCSP.Sign.CryptoProSign.engineInitSign(Unknown Source:7) I/(11282): at java.security.Signature.initSign(Signature.java:679)
Инициализация криптопровайдера на эмуляторе initEMULATOR.txt (3kb) загружен 3 раз(а).Инициализация криптопровайдера на телефоне initDevice.txt (31kb) загружен 2 раз(а).Установка контейнера на эмуляторе installEmulator.txt (3kb) загружен 3 раз(а).Установка контейнера на телефоне installDevice.txt (9kb) загружен 7 раз(а).Спасибо за помощь
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,963 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 704 раз в 665 постах
|
Ошибка "java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.security.PrivateKey.getAlgorithm()' on a null object reference" закономерна - ведь Key == null после чтения. Полезные логи в последнем приложенном файле, сверху ошибки. Какая у вас версия CSP SDK? |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 31.07.2020(UTC) Сообщений: 9
|
Версия CSP 4, а вот номер ревизии не могу вспомнить и не вижу где его посмотреть
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,963 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 704 раз в 665 постах
|
|
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 31.07.2020(UTC) Сообщений: 9
|
Логи установки сертификата на эмулятор были не все installEmulator2.txt (10kb) загружен 3 раз(а).Вот теперь четко я вижу, что на эмуляторе загружается приватный ключ (Loading the private key...), а на телефоне нет(Adding certificate only.) Попробую установить 5ую версию CSP, хорошо
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 31.07.2020(UTC) Сообщений: 9
|
Обновился на 5ую версию, все заработало, спасибо! Есть еще вопрос Как ввести лицензию до инициализации провайдера? Метод из примера:
CSPProviderInterface providerInfo = CSPConfig.INSTANCE.getCSPProviderInfo(); LicenseInterface license = providerInfo.getLicense();
не работает, т.к CSPProviderInterface инициализируется в CSPConfig.init после проверки лицензии, на которой он делает return, ибо лицензия недействительна; А способ:
String licenseFilePath = context.getApplicationInfo().dataDir + File.separator + "cprocsp" + File.separator + "etc" + File.separator + "license.ini"; ACSPLicense acspLicense = new ACSPLicense(licenseFilePath); acspLicense.checkAndSave(license, false);
требует перезагрузки приложения, что не очень приятно.
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close