使用BouncyCastle验证Android KeyStore签名的有效负载



我正在尝试使用Android的KeyStore API对数据进行签名,并使用BouncyCastle和C#验证服务器中的数据。

我的验证过程是这样的:

  1. 在android上生成密钥对
  2. 将公钥发送到服务器
  3. 在服务器上生成质询
  4. 使用私钥在android上签署挑战
  5. 使用公钥验证服务器上已签名的质询

我无法使验证正常工作。如何使验证成功?是否存在重大逻辑错误?

这是我现在使用的代码:

使用KeyPairGenerator:生成密钥对

val generator: KeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
val parameterSpec: KeyGenParameterSpec = KeyGenParameterSpec.Builder("KEY_ALIAS",
KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
)
.setDigests(KeyProperties.DIGEST_SHA256)
.setKeySize(2048)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS)
.build()
generator.initialize(parameterSpec)
generator.generateKeyPair()

获取发送到服务器的公钥:

val publicKeyBytes = keyStore.getCertificate("KEY_ALIAS").publicKey.encoded
val publicKey = Base64.encodeToString(publicKeyBytes, Base64.DEFAULT)

然后,服务器生成一个挑战负载,该负载必须由安卓应用程序验证。签名是这样完成的:

val challengeBytes = Base64.decode(challenge, Base64.DEFAULT)
val entry = keyStore.getEntry("KEY_ALIAS", null) as KeyStore.PrivateKeyEntry
val signature = Signature.getInstance("SHA256withRSA/PSS")
signature.initSign(entry.privateKey)
signature.update(challengeBytes)
val signedBytes = signature.sign()
val signedChallenge = Base64.encodeToString(signedBytes, Base64.NO_WRAP)

然后将该signedChallenge发送到服务器,服务器将使用C#中的BouncyCastle进行验证:

byte[] challengeBytes = // Original challenge
byte[] signedBytes = Convert.FromBase64String(signedChallenge);
ISigner signer = SignerUtilities
.GetSigner(
SignerUtilities
.GetObjectIdentifier("SHA256withRSA/PSS"));
var pKeyParams = (RsaKeyParameters) PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
signer.Init(false, pKeyParams);
signer.BlockUpdate(challengeBytes, 0, challengeBytes.Length);
isVerified = signer.VerifySignature(signedBytes);

设置

安卓:SDK 23+服务器是使用NuGet Package Portable用C#编写的。BouncyCastle 1.8.10版

问题是C#代码中ISigner的实例化。

为了让它发挥作用,我必须让签名者这样:

ISigner signer = SignerUtilities.GetSigner("SHA256withRSA/PSS"); 

相关内容

  • 没有找到相关文章

最新更新