KeyPairGenerator挂起UI

时间:2020-07-24 10:17:21

标签: android encryption cryptography

问题是generatorOfKeyPairs.generateKeyPair()挂起了UI,而不管它是在主线程还是 background 线程上执行的。
对于中档电话,时间为2-20秒。对于便宜的设备,时间最多需要一分钟。在Log.d(TAG, "start");Log.d(TAG, "end");之间测量的时间 该如何解决?
PS。
"AndroidKeyStore"以外的安全提供程序不会挂起UI,但是我必须使用它,因为它更安全,因为永远不会公开私钥材料。

用于生成KeyPair的代码:

public class MainActivity extends AppCompatActivity
{
    private static final String TAG = MainActivity.class.getSimpleName();
    private final Handler mainThreadHandler = new Handler();

    @BindView(R.id.start_button)
    Button start_button;
    @BindView(R.id.time_text)
    TextView time_text;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        start_button.setOnClickListener(view ->
        {
            Log.d(TAG, "hang_button click");

            start_button.setEnabled(false);
            time_text.setText("Started");

            generateKeypairAsync();
        });
    }

    private void generateKeypairAsync()
    {
        // Main thread

        mainThreadHandler.post(() ->
        {
            AsyncTask.execute(() ->
            {
                // Background thread

                KeypairGenerationResult res = generateKeypair("alias_of_key");

                mainThreadHandler.post(() ->
                {
                    // Main thread

                    start_button.setEnabled(true);
                    time_text.setText(String.format("Time: %.2f", res.generationTimeMs / 1000.0));
                });
            });
        });
    }

    /**
     * Method to generate KeyPair synchronously.
     */
    private static KeypairGenerationResult generateKeypair(String aliasOfKey)
    {
        Calendar dateValidFrom = Calendar.getInstance();
        Calendar dateValidTo = Calendar.getInstance();
        dateValidTo.add(Calendar.YEAR, 1);
        KeyGenParameterSpec specOfKey = new KeyGenParameterSpec.Builder(aliasOfKey, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setKeySize(4096)
                .setKeyValidityStart(dateValidFrom.getTime())
                .setKeyValidityEnd(dateValidTo.getTime())
                .setCertificateSerialNumber(BigInteger.ONE)
                .setCertificateSubject(new X500Principal(String.format("CN=%s", "CertName")))
                .setDigests(KeyProperties.DIGEST_SHA256)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
                .build();

        try
        {
            KeyPairGenerator generatorOfKeyPairs = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore");
            generatorOfKeyPairs.initialize(specOfKey);

            Log.d(TAG, "start");

            long timeStart = System.currentTimeMillis();
            KeyPair keyPair = generatorOfKeyPairs.generateKeyPair();
            long timeDiff = System.currentTimeMillis() - timeStart;

            Log.d(TAG, "end, time ms: " + timeDiff);

            return new KeypairGenerationResult(keyPair, timeDiff);
        }
        catch (GeneralSecurityException ex)
        {
            Log.e(TAG, "Cannot generate wrapping keypair, exception: " + ex.getClass().getSimpleName() + " " + ex.getMessage());
            return null;
        }
    }
}

使用此方法的示例Android Studio项目在此处:https://github.com/Mr-Goldberg/KeyPairGeneratorSpeedTest

0 个答案:

没有答案