2017-08-26 104 views
0

我有一些令牌,需要先使用基於KeyStore的私鑰和公鑰的SHA256和ECDSA對其進行簽名。ECDSA使用公鑰進行Android驗證總是返回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; 
} 

回答

0

錯誤在這裏,當您編寫以下代碼來驗證簽名時:

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等。