Как разрешить криптографические изменения в Android P? - PullRequest
2 голосов
/ 16 июня 2019

Прежде всего, я новичок в этой операции шифрования, и я не знаю, правильно ли задавать мой вопрос или нет! приветствуется любое решение ...

В моем проекте я использую этот код для создания SSLSocketFactory для сервисов:

  public static SSLSocketFactory getGlobalSSlFactory() {
   try {
    CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
    InputStream caInput = context.getResources().openRawResource(xxxxxxx);

    Certificate ca = cf.generateCertificate(caInput);
    caInput.close();

    KeyStore keyStore = KeyStore.getInstance("BKS");
    keyStore.load(null, null);

    keyStore.setCertificateEntry("ca", ca);

    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);

    KeyManagerFactory kmf = KeyManagerFactory.getInstance(
            KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(keyStore, "xxxxxxx".toCharArray());

    final SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, tmf.getTrustManagers(), null); 
       return sslContext.getSocketFactory();
  } catch (Exception e) {
     e.printStackTrace();
     return null;
  }
}

Ошибка, которую я получаю при тестировании на устройстве с Android (Pie):

error

Google говорит: https://android -developers.googleblog.com / 2018/03 / cryptography-changes-in-android-p.html

Важная часть:

«Чтобы решить эту проблему, вы должны прекратить указывать поставщика и использовать реализацию по умолчанию.»

Как мне изменить мой код?

** больше объяснений **

Я сделал то, что сказал @sonhvp, но после тестирования появилась эта ошибка:

error in log

И ошибка приходит к этой строке:

 Certificate ca = cf.generateCertificate(caInput);

Это моя версия для Android:

my android version

1 Ответ

2 голосов
/ 16 июня 2019

Как сказано в документе: «Начиная с Android N, мы не рекомендуем указывать поставщика».Так что просто удалите всех провайдеров в вашем крипто.
В вашем методе

CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");

удалить провайдера ("BC")

CertificateFactory cf = CertificateFactory.getInstance("X.509");

Другие методы в порядке.Поскольку в нем не указан поставщик

KeyStore.getInstance("BKS"); //no provider
TrustManagerFactory.getInstance(tmfAlgorithm); //no provider
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); //no provider
SSLContext.getInstance("TLS"); //no provider

Что-то не так с вашим файлом сертификата в папке raw.Я создал файл сертификата и запустил его с вашим кодом без каких-либо проблем.Просто измените на CertificateFactory.getInstance("X.509").Попробуйте с моим файлом сертификата

public class Test {

    public Test(AppCompatActivity activity) {
        context = activity;
    }

    private Context context;

    public  SSLSocketFactory getGlobalSSlFactory() {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = context.getResources().openRawResource(R.raw.test);

            Certificate ca = cf.generateCertificate(caInput);
            caInput.close();

            KeyStore keyStore = KeyStore.getInstance("BKS");
            keyStore.load(null, null);

            keyStore.setCertificateEntry("ca", ca);

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            KeyManagerFactory kmf = KeyManagerFactory.getInstance(
                    KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(keyStore, "xxxxxxx".toCharArray());

            final SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

}

Моя активность

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val test = Test(this)
        test.globalSSlFactory.createSocket()
    }

}
...