几个需要注意的地方

1、安卓的KeyFactory如果要支持EC加密,必须使用Java11的JDK版本(SpringBoot开发可以支持Java8,亲测),源码说明如下图:

alt

2、publicKey和privateKey的编码格式不一样,在传递过程中如果需要反序列化得到钥匙切记注意(本人踩坑):

(1)publicKey的编码为:X509EncodedKeySpec

(2)privateKey的编码为:PKCS8EncodedKeySpec

3、代码如下:若SpringBoot开发也需要,也可使用该套代码,将@UniJSMethod注解和callback参数去掉即可。

/**
     * 生成ECDHE密钥对
     *
     * @return 密钥对
     * @throws NoSuchAlgorithmException
     */
    @UniJSMethod
    public void generateECKeyPair(UniJSCallback callback) throws Exception {
        final KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
        generator.initialize(256); // Set p=256
        KeyPair keyPair = generator.generateKeyPair();
        ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
        ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
        String publicKeyString = Base64.encodeBase64String(ecPublicKey.getEncoded());
        String privateKeyString = Base64.encodeBase64String(ecPrivateKey.getEncoded());
        ECKeyPair ecKeyPair = new ECKeyPair(publicKeyString, privateKeyString);
        Log.i(TAG, "===============TestModule============生成的EC秘钥对:" + ecKeyPair);
        callback.invoke(new JSONObject() {{
            put("code", 2000);
            put("result", ecKeyPair);
        }});
    }
 /**
     * 生成共享密钥
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     * @throws InvalidKeyException
     */
    @UniJSMethod
    public void deriveSharedSecret(JSONObject json, UniJSCallback callback) throws NoSuchAlgorithmException, InvalidKeyException {
        String otherPublicKeyStr = json.getString("otherPublicKey");
        String yourPrivateKeyStr = json.getString("yourPrivateKey");
        byte[] otherKeys = Base64.decodeBase64(otherPublicKeyStr);
        byte[] yourKeys = Base64.decodeBase64(yourPrivateKeyStr);
        final KeyFactory ec = KeyFactory.getInstance("EC");
        final X509EncodedKeySpec keySpecPb = new X509EncodedKeySpec(otherKeys);
        final PKCS8EncodedKeySpec keySpecPr = new PKCS8EncodedKeySpec(yourKeys);
        Log.i(TAG, "===================================================================下面开始反序列化生成钥匙");
        PublicKey publicKey = null;
        try {
            publicKey = ec.generatePublic(keySpecPb);
            Log.i(TAG, "===================================================================公钥生成成功");
        } catch (InvalidKeySpecException e) {
            Log.e(TAG, "===================================================================公钥生成失败", e);
        }
        PrivateKey privateKey = null;
        try {
            privateKey = ec.generatePrivate(keySpecPr);
            Log.i(TAG, "===================================================================私钥生成成功");
        } catch (InvalidKeySpecException e) {
            Log.e(TAG, "===================================================================私钥生成失败", e);
        }
        Log.i(TAG, "===================================================================成功获得了反序列化的钥匙");
        KeyAgreement ecdh = KeyAgreement.getInstance("ECDH");
        Log.i(TAG, "===================================================================下面开始ECDH生成器");
        ecdh.init(privateKey);
        ecdh.doPhase(publicKey, true);
        byte[] shareKey = ecdh.generateSecret();
        String finalShareKey = Base64.encodeBase64String(shareKey);
        callback.invoke(new JSONObject() {{
            put("code", 2000);
            put("result", finalShareKey);
        }});
    }
/**
     * DH密钥对对象
     */
    public class ECKeyPair {
        private String ecPublicKey;
        private String ecPrivateKey;

        public ECKeyPair(String ecPublicKey, String ecPrivateKey) {
            this.ecPublicKey = ecPublicKey;
            this.ecPrivateKey = ecPrivateKey;
        }

        public String getEcPublicKey() {
            return ecPublicKey;
        }

        public String getEcPrivateKey() {
            return ecPrivateKey;
        }


    }