问题是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