有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

安卓 java。安全实现DH协议时的InvalidKeyException

在我的安卓应用程序中,我想实现Diffie-Hellman协议,以便在两个用户之间生成一个公共密钥

我所做的是:当第一个用户向第二个用户发送友谊请求时,应用程序生成一个密钥对,将公共密钥对存储在远程数据库中,将私有密钥对存储在本地数据库中

以下是第一部分的代码:

generateKeys();
localDB.insertPrivateKey(userId, entityId, privateKey);
remoteDB.insertFirstPublicKey(userId, entityId, publicKey);

generateKeys方法如下所示:

private void generateKeys() {
        try {
            final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
            keyPairGenerator.initialize(1024);

            final KeyPair keyPair = keyPairGenerator.generateKeyPair();

            privateKey = keyPair.getPrivate();
            publicKey  = keyPair.getPublic();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

当第二个用户接受请求时,会生成另一个密钥对,再次将私钥存储在本地数据库中,将公钥存储在远程数据库中。然后它从远程数据库获取第一个用户的公钥,将其转换回公钥并生成公共密钥

以下是第二部分的代码:

generateKeys();
localDB.insertPrivateKey(userId, entityId, privateKey);
remoteDB.insertSecondPublicKey(entityId, userId, publicKey);
String stringFirstPubKey = remoteDB.fetchFirstKey(entityId, userId);
PublicKey firstPubKey = stringToPublicKey(stringFirstPubKey);
byte[] commonSecret = generateCommonSecret(firstPubKey);

StringToPublicey如下所示:

private PublicKey stringToPublicKey(String stringPubK) throws NoSuchAlgorithmException, InvalidKeySpecException {
    byte[] pubK = Base64.decodeBase64(stringPubK);
    KeyFactory keyFactory = KeyFactory.getInstance("DH");
    EncodedKeySpec keySpec = new X509EncodedKeySpec(pubK);
    return keyFactory.generatePublic(keySpec);
}

还有一个秘密:

private byte[] generateCommonSecret(PublicKey firstPubKey) {
    try {
        final KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
        keyAgreement.init(privateKey);
        keyAgreement.doPhase(firstPubKey, true);
        byte[] secretKey = adjustKeyLenght(keyAgreement.generateSecret());
        return secretKey;
    } catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

此外,在存储密钥时,我会将它们转换为字符串,如下所示:

String stringPubK = Base64.encodeBase64String(publicKey.getEncoded());

在generateCommonSecret中执行以下行时

keyAgreement.doPhase(firstPubKey, true);

我有个例外

java.security.InvalidKeyException: DHPublicKey not for this KeyAgreement!   
at com.安卓.org.bouncycastle.jcajce.provider.asymmetric.dh.KeyAgreementSpi.engineDoPhase(KeyAgreementSpi.java:101)
at javax.crypto.KeyAgreement.doPhase(KeyAgreement.java:383)

有人能帮我找到问题吗?奇怪的是,如果我尝试在一个java类中实现这一点,而不存储和检索键,它就可以正常工作


共 (0) 个答案