当前位置: 首页 > 知识库问答 >
问题:

ECDSA Android使用公钥验证始终返回false

冯德宇
2023-03-14

我有一些令牌,我需要首先与SHA256和ECDSA基于私钥和公钥从KeyStore签名。

每次我尝试验证值时,结果都是false。我不知道为什么。

有人知道怎么解决这个问题吗?

下面是我生成和加载密钥的函数:

private void generateKeys(){

    try {

        keyStore = KeyStore.getInstance(KEYSTORE_NAME);
        keyStore.load(null);

        if(!keyStore.containsAlias(KEY_NAME)) {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, KEYSTORE_NAME);
            keyPairGenerator.initialize(
                    new KeyGenParameterSpec.Builder(KEY_NAME,
                            KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
                            .setDigests(KeyProperties.DIGEST_SHA256,
                                    KeyProperties.DIGEST_SHA512)
                            .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                            .setUserAuthenticationRequired(false)
                            .build());
            keyPairGenerator.generateKeyPair();

            setRegistred(true);
        }
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}



private void loadKeys(){
    try {
        keyStore = KeyStore.getInstance(KEYSTORE_NAME);
        keyStore.load(null);
        if(keyStore.containsAlias(KEY_NAME)) {
            publicKey = keyStore.getCertificate(KEY_NAME).getPublicKey();
            privateKey = (PrivateKey) keyStore.getKey(KEY_NAME, null);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (UnrecoverableKeyException e) {
        e.printStackTrace();
    }
}

这就是符号值的含义:

 public String sign(String inputStr, FingerprintManager.CryptoObject cryptoObject){
    try {
        Signature signature = Signature.getInstance(SecurityConstants.SIGNATURE);
        signature.initSign(privateKey);
        signature.update(inputStr.getBytes());
        byte[] signedBytes = signature.sign();
        String result = Base64.encodeToString(signedBytes, Base64.DEFAULT);
        Log.d("TAG", result);
        return result;
    } catch (SignatureException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}

以下是我尝试使用公钥进行验证的步骤:

public boolean verifyWithPublicKey(String input, FingerprintManager.CryptoObject cryptoObject){
    try {
        Signature signature = Signature.getInstance(SecurityConstants.SIGNATURE);
        keyStore = KeyStore.getInstance(KEYSTORE_NAME);
        keyStore.load(null);
        PublicKey pk  = getPublicKeyForVerification();
        signature.initVerify(pk);
        signature.update(input.getBytes());
        boolean isVerifed = signature.verify(input.getBytes());
        Log.d("TAG", String.valueOf(isVerifed));
        return isVerifed;
    } catch (SignatureException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (CertificateException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

共有1个答案

黄无尘
2023-03-14

当您编写以下代码来验证签名时,错误在此处:

signature.update(input.getBytes());
boolean isVerifed = signature.verify(input.getBytes());

使用此代码,您可以尝试验证签名是否已与自身签名!

你应该有:

signature.update(MY_BYTES_ARRAY_OF_DATA);
boolean isVerifed = signature.verify(MY_SIGNATURE);

不要忘记,默认情况下,签名不会封装已签名的数据。

如果您想要包含签名数据和相关签名的格式,请使用S/MIME、OpenPGP等。

 类似资料:
  • 我想验证一些来自Microsoft的JWT的签名。我正在使用Spring-Boot、JJWT库和以下endpoint:https://login.microsoftonline.com/common/discovery/v2.0/keys endpoint返回JSON公钥数组。下面是数组中的一个示例。

  • 通常情况下,访问远程服务器上的 Git 仓库要受到限制。你可能不希望任何人都能读取文件,或者至少不能改动文件吧。在这种情况下,进行有效的认证就是非常必要地。 你可能已经通过你所使用的浏览器了解了 “HTTPS” 协议,尽管它使用起来很简单,但是很多系统管理员还是会出于各种原因去选择使用更为普遍的 “SSH” 协议。在这种协议之下,当涉及到身份验证时,你就很可能需要 “SSH公钥”。 对于这种类型的

  • 问题内容: 我有一个外部服务,在定义的事件发生后会给我回电,并用其私钥签署他的请求。 我已经存储了如下公钥: 因此,我的工作是通过验证签名来检查请求的内容是否未更改。 这是我的算法: 但是目前,我的算法已停止在此消息的“ PublicKey publicKey = keyFactory.generatePublic(publicKeySpec)”步骤处: 那么,如何以java api接受的方式加载

  • 验证应用程序: 据我所知.pfx文件包含公钥和私钥信息,因此我不应该让任何人都可以使用它。据我所知,验证步骤只需要公钥。我如何使用rsa.verifydata或其他函数来验证签名而不暴露我的pfx文件?

  • 我需要用DSA公钥验证X509证书签名。我的证书文件x509.crt,我的DSA公钥在一个名为dsa_pub.key的文件中 我正试图为此使用openssl。我已经阅读了openssl验证文档,但在其中找不到任何有关DSA的参考。 当我运行以下命令时,我可以在证书中看到我的DSA公钥: 但是,在使用文件DSA_pub.key中的DSA公钥验证cert.crt时,我遇到了麻烦 如果您有任何建议,我将

  • 我想知道如何使用公钥来验证私钥。 “<代码> <模数> 这是一个字符串,我试图使用Python验证它的私钥(也是作为字符串提供的)。我知道发行人和观众需要做什么,但我不确定如何处理所有这些信息。 我看了一些peoples使用各种包的例子,但我似乎不知道pub_key、private_key和message是什么类型...请帮帮我...我希望学习