java.security.NoSuchAlgorithmException:没有这样的算法:提供商 BC 的 ECDSA

java.security.NoSuchAlgorithmException: no such algorithm: ECDSA for provider BC

我正在尝试使用 KeyPairGenerator 函数生成 secp256k1 密钥对。我的功能看起来像

public fun generateSECP256K1Keypair():KeyPair{
  Security.addProvider(org.bouncycastle.jce.provider.BouncyCastleProvider())
  var keypairGen: KeyPairGenerator = KeyPairGenerator.getInstance("ECDSA","BC")
  val spec:ECGenParameterSpec = ECGenParameterSpec("secp256k1")
  keypairGen.initialize(spec, SecureRandom())
  var keyPair:KeyPair= keypairGen.genKeyPair()
  return keyPair;

}

我的 gradle 文件依赖项如下所示

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.bouncycastle:bcprov-jdk15on:1.61'

}

当我尝试执行此函数时,出现以下错误

Process: com.example.myapplication, PID: 6477
java.lang.RuntimeException: Unable to create service com.example.myapplication.service.Myservice: java.security.NoSuchAlgorithmException: no such algorithm: ECDSA for provider BC
    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3201)
    at android.app.ActivityThread.-wrap5(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1567)
    at android.os.Handler.dispatchMessage(Handler.java:102)

如果我使用 SpongyCastle 而不是 BouncyCastle,它工作正常。但我不想在我的案例中使用 SpongyCastle 提供程序。

我找到了这个,读了这个。

Android 自 4.0 版以来引入了对 ECDSA 的支持,使用 Bouncycastle (v1.46) 作为默认加密提供程序。查看博客 https://nelenkov.blogspot.com.es/2011/12/using-ecdh-on-android.html?m=1

但是 Android 包含了 Bouncycastle 的简化版本,并且没有对 ECDSA 的完全支持。您可以在 link 中看到不支持算法 KeyPairGenerator/ECDSA,这是生成以太坊密钥所需的算法。

您不能直接包含 bouncycastle 库,因为与包名有冲突 org.bouncycastle。我建议在您的项目中包含 spongycastle,它是 Android org.spongycastle.

的 bouncycastle 的重新打包版本

包名称冲突已在新 android 版本中解决,但如果您的目标是旧版本,则需要确保使用的是哪个加密提供程序。

bouncycastle 和 spongycastle 之间存在包名冲突。

Spongycastle 是 BouncyCastle 的重新编译和测试版本。如果你真的想使用 Bouncycastle,我认为唯一的解决方案是在你的应用程序中包含 bouncycastle 的整个源代码,重命名包名称

这段代码对我来说很好用

public fun generateSECP256K1Keypair():KeyPair{
  Security.addProvider(org.bouncycastle.jce.provider.BouncyCastleProvider())
  var keypairGen: KeyPairGenerator = KeyPairGenerator.getInstance("EC","BC")
  val spec:ECGenParameterSpec = ECGenParameterSpec("secp256k1")
  keypairGen.initialize(spec, SecureRandom())
  var keyPair:KeyPair= keypairGen.genKeyPair()
  return keyPair;