Как проверить ECDSA с открытым ключом? - PullRequest
0 голосов
/ 20 мая 2019

У меня есть следующие способы генерации ключей и подписи сообщения о пароле.

public 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)
            .setDigests(KeyProperties.DIGEST_SHA256)
            .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
            // Require the user to authenticate with a fingerprint to authorize
            // every use of the private key
            .setUserAuthenticationRequired(true)
            .build());
    keyPairGenerator.generateKeyPair();
  }

  loadKeys();
} 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();
}

}

public BiometricPrompt.CryptoObject getCryptoObject() {
cryptoObject = new BiometricPrompt.CryptoObject(signature);
return cryptoObject;
}

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);
    signature = Signature.getInstance(Constants.SIGNATURE);
    signature.initSign(privateKey);
  }
} 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();
} catch (InvalidKeyException e) {
  e.printStackTrace();
}
}

public String sign(String inputStr) {
try {
  Signature signature = cryptoObject.getSignature();
  signature.update(inputStr.getBytes());
  byte[] signedBytes = signature.sign();
  String result = HexManager.bytesToHex(signedBytes);
  Log.d("TAG", result);
  return result;
} catch (SignatureException e) {
  e.printStackTrace();
}
return null;

}

После этого я сохранил подписанный пароль в общих настройках. Позже я хочу проверить сохраненный пароль с помощью нового пароля, который проверяется по отпечатку пальца.

Вот мой метод проверки:

public boolean verify(String inputStr, String savedStr) {
try {
  Signature signature = cryptoObject.getSignature();
  signature.initVerify(publicKey);
  signature.update(inputStr.getBytes());
  boolean isVerified = signature.verify(savedStr.getBytes());
  return isVerified;
} catch (InvalidKeyException e) {
  e.printStackTrace();
} catch (SignatureException e) {
  e.printStackTrace();
}
return false;
}

Но всегда возвращается false.

Кто-нибудь знает почему?

enter image description here

1 Ответ

1 голос
/ 31 мая 2019

Похоже, что в вашем методе sign() вы возвращаете Hex из byte[], полученного из метода signature.sign().Если это то, что вы сохраняете как savedStr.Затем следует изменить метод проверки, чтобы преобразовать кодированную строку Hex в byte[].Вы можете использовать HexManager.hexToBytes() (или эквивалент), если он существует, для преобразования savedStr в byte[] savedStrBytes.

public boolean verify(String inputStr, String savedStr) {
    try {
        byte[] savedStrBytes = HexManager.hexToByes(savedStr);
        Signature signature = cryptoObject.getSignature();
        signature.initVerify(publicKey);
        signature.update(inputStr.getBytes());
        boolean isVerified = signature.verify(savedStrBytes);
        return isVerified;
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (SignatureException e) {
        e.printStackTrace();
    }
    return false;
}
...