我正在尝试在Android上实施ECDH,并设法获取测试密钥协议的代码(完整代码如下所示)
不幸的是,当我运行代码时,它给了我一个java.security.NoSuchAlgorithmException:找不到KeyPairGenerator ECDH实现。
这是我所涉及的问题
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "BC");
正如我所指出的,有人提到过Android上并不完全支持BouncyCastle,而是使用我拥有的SpongyCastle。我也尝试将提供商从“BC”改为“SC”
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "SC");
不幸的是,这给了我一个java.security.NoSuchProviderException:SC
希望有人可以给我一些指导。非常感谢!
部分testECDH()代码:
import org.spongycastle.jce.ECPointUtil;
import org.spongycastle.jce.provider.BouncyCastleProvider;
import org.spongycastle.util.encoders.Hex;
import org.spongycastle.util.test.SimpleTest;
private void testECDH()
{
try
{
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH", "SC");
EllipticCurve curve = new EllipticCurve(
new ECFieldFp(new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839")), // q
new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a
new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b
ECParameterSpec ecSpec = new ECParameterSpec(
curve,
ECPointUtil.decodePoint(curve, Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"), // n
1); // h
g.initialize(ecSpec, new SecureRandom());
//
// a side
//
KeyPair aKeyPair = g.generateKeyPair();
KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH", "SC");
aKeyAgree.init(aKeyPair.getPrivate());
//
// b side
//
KeyPair bKeyPair = g.generateKeyPair();
KeyAgreement bKeyAgree = KeyAgreement.getInstance("ECDH", "SC");
bKeyAgree.init(bKeyPair.getPrivate());
//
// agreement
//
aKeyAgree.doPhase(bKeyPair.getPublic(), true);
bKeyAgree.doPhase(aKeyPair.getPublic(), true);
BigInteger k1 = new BigInteger(aKeyAgree.generateSecret());
BigInteger k2 = new BigInteger(bKeyAgree.generateSecret());
if (!k1.equals(k2))
{
fail("ECDH 2-way test failed");
}
//
// public key encoding test
//
byte[] pubEnc = aKeyPair.getPublic().getEncoded();
KeyFactory keyFac = KeyFactory.getInstance("ECDH", "SC");
X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
ECPublicKey pubKey = (ECPublicKey)keyFac.generatePublic(pubX509);
if (!pubKey.getW().equals(((ECPublicKey)aKeyPair.getPublic()).getW()))
{
System.out.println(" expected " + pubKey.getW().getAffineX() + " got " + ((ECPublicKey)aKeyPair.getPublic()).getW().getAffineX());
System.out.println(" expected " + pubKey.getW().getAffineY() + " got " + ((ECPublicKey)aKeyPair.getPublic()).getW().getAffineY());
fail("ECDH public key encoding (W test) failed");
}
if (!pubKey.getParams().getGenerator().equals(((ECPublicKey)aKeyPair.getPublic()).getParams().getGenerator()))
{
fail("ECDH public key encoding (G test) failed");
}
//
// private key encoding test
//
byte[] privEnc = aKeyPair.getPrivate().getEncoded();
PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
ECPrivateKey privKey = (ECPrivateKey)keyFac.generatePrivate(privPKCS8);
if (!privKey.getS().equals(((ECPrivateKey)aKeyPair.getPrivate()).getS()))
{
fail("ECDH private key encoding (S test) failed");
}
if (!privKey.getParams().getGenerator().equals(((ECPrivateKey)aKeyPair.getPrivate()).getParams().getGenerator()))
{
fail("ECDH private key encoding (G test) failed");
}
}
catch (Exception e)
{
fail("ECDH 2-way test failed - exception: " + e);
}
}