Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 苹果品种加密辅助因子可变IVX963SHA256ESGCM与BouncyCastle ECCDH(含SHA256KDF)_Java_Ios_Bouncycastle_Aes Gcm_Ecies - Fatal编程技术网

Java 苹果品种加密辅助因子可变IVX963SHA256ESGCM与BouncyCastle ECCDH(含SHA256KDF)

Java 苹果品种加密辅助因子可变IVX963SHA256ESGCM与BouncyCastle ECCDH(含SHA256KDF),java,ios,bouncycastle,aes-gcm,ecies,Java,Ios,Bouncycastle,Aes Gcm,Ecies,我正在尝试使用Apple算法加密Java()和iOS之间的通信 苹果的算法并没有很好的文档记录,但我发现这非常有帮助 我还发现,在中的以下算法似乎与我正在寻找的算法非常接近: ECCDH使用SHA256KDF表示EC辅因子DH,使用X9.63 KDF和SHA256作为PRF package com.example.ios.encryption; 导入org.bouncycastle.jce.ECNamedCurveTable; 导入org.bouncycastle.jce.ECPointUt

我正在尝试使用Apple算法加密Java()和iOS之间的通信

苹果的算法并没有很好的文档记录,但我发现这非常有帮助

我还发现,在中的以下算法似乎与我正在寻找的算法非常接近:

  • ECCDH使用SHA256KDF
    表示EC辅因子DH,使用X9.63 KDF和SHA256作为PRF
package com.example.ios.encryption;
导入org.bouncycastle.jce.ECNamedCurveTable;
导入org.bouncycastle.jce.ECPointUtil;
导入org.bouncycastle.jce.provider.BouncyCastleProvider;
导入org.bouncycastle.jce.spec.ECNamedCurveSpec;
导入org.bouncycastle.jce.spec.ECParameterSpec;
导入org.bouncycastle.util.encoders.Base64;
导入java.math.biginger;
导入java.security.*;
导入java.security.spec.ECPoint;
导入java.security.spec.ECPrivateKeySpec;
导入java.security.spec.ECPublicKeySpec;
导入java.util.array;
导入javax.crypto.Cipher;
导入javax.crypto.KeyAgreement;
导入javax.crypto.SecretKey;
导入javax.crypto.spec.gcmpareterspec;
导入javax.crypto.spec.SecretKeySpec;
公共类IOSNyptioneCWithAES{
公共void testDecrypt(){
//接收方EC公钥
String publikeybase64=“BBPT50Rn0PeeV0LxUbhDV7U1FUgVw9YLVctQx5HA+TiA3lp3k/cud8Xsjh6lytgaI5S7IUW1YouUiPNR/7LPArk=”;
PublicKey pubKey=getPublicKey(Base64.decode(pubKeyBase64));
//接收方EC私钥
String privateKeyBase64=“BBPT50RN0PEEV0LXUBHDV7U1FUGV9YLVCTQX5HA+TiA3lp3k/cud8Xsjh6lytgaI5S7IUW1YouUiPNR/7LPArkWcIYOQWtdkbTqmy++LZ0CQ8UKWVUYHD9YZQHPLQGQG=”;
PrivateKey PrivateKey=getPrivateKey(Base64.decode(privateKeyBase64));
//加密数据
字符串iosOutputBase64=“BNNzHjSJQxP8jNuj5W9XSW0XNgpOlEHY/S4KZZZQJFXWJZUJUWZ5KJEOLJ6CASBayKEPGLHKBE0QN20Y8AHPU+PMEUDJWY7LZ25LJVutafoJUGDRZDURRWFSKE7HZHXLSNEATFEGT3OOQ9FFJCYNWD7IRD”;
字节[]iosOutput=Base64.decode(iosOutputBase64);
//明文是一种随机UUID
字符串明文=“514227F0-51E9-41AC-9A39-42752E2ABADF”;
byte[]decryptedData=DecryptedIncryptionCofactorVariableIVX963SHA256AESGCM(私钥,iosOutput);
System.out.println(新字符串(decryptedData));
}
公共字节[]DecryptECiseEncryptionCofactorVariableIVX963SHA256AESGCM(私钥私钥,字节[]IOSUPPUT)引发异常{
//1.获取临时公钥
byte[]ephemeralKeyBytes=Arrays.copyOfRange(iosOutput,0,65);
PublicKey ephemeralPublicKey=getPublicKey(ephemeralKeyBytes);
字节[]encryptedData=Arrays.copyOfRange(iosOutput,65,iosOutput.length);
//2.使用ECDH与辅因子和集成X9.63的密钥协议
字节[]kdfOut=getSharedSecret(临时公共密钥,私钥);
byte[]secretKeyBytes=Arrays.copyOfRange(kdfOut,0,16);
SecretKey SecretKey=newsecretkeyspec(secretKeyBytes,“AES”);
//4.使用AES密钥解密
int tagLength=128;
字节[]iv=Arrays.copyOfRange(kdfOut,16,kdfOut.length);
GCMPareterSpec aesGcmParams=新GCMPareterSpec(标记长度,iv);
Cipher c=Cipher.getInstance(“AES/GCM/NoPadding”);
c、 init(Cipher.DECRYPT_模式,secretKey,AESGComparams);
字节[]decryptedData=c.doFinal(encryptedData);
返回解密数据;
}
/**
*使用BouncyCastle将未压缩的公钥转换为公钥
*对于椭圆曲线公钥,格式遵循ANSI X9.63标准
*使用04 | | X | | Y的字节字符串
*
*@param encodedBytes已接收原始字节
*@返回基于曲线SECP256R1的椭圆曲线公钥
*/
私有公钥getPublicKey(字节[]encodedBytes)引发异常{
KeyFactory KeyFactory=KeyFactory.getInstance(“EC”);
ECParameterSpec ECParameterSpec=ECNamedCurveTable.getParameterSpec(“secp256r1”);
ECNamedCurveSpec params=新的ECNamedCurveSpec(“secp256r1”,ecParameterSpec.getCurve(),ecParameterSpec.getG(),ecParameterSpec.getN());
ECPoint publicPoint=ECPointUtil.decodePoint(params.getCurve(),encodedBytes);
ECPublicKeySpec pubKeySpec=新的ECPublicKeySpec(publicPoint,参数);
返回keyFactory.generatePublic(pubKeySpec);
}
/**
*将私钥转换为iOS的外部输出
*对于椭圆曲线私钥,输出格式为公钥
*与秘密标量或04 | | X | | Y | K的大端编码连接。
*
*@param encodedBytes已接收原始字节
*@返回基于曲线SECP256R1的椭圆曲线私钥
*/
private PrivateKey getPrivateKey(字节[]encodedBytes)引发异常{
BigInteger s=新的BigInteger(Arrays.copyOfRange(encodedBytes,65,encodedBytes.length));
ECParameterSpec ECParameterSpec=ECNamedCurveTable.getParameterSpec(“secp256r1”);
ECNamedCurveSpec params=新的ECNamedCurveSpec(“secp256r1”,ecParameterSpec.getCurve(),ecParameterSpec.getG(),ecParameterSpec.getN());
ECPrivateKeySpec privateKeySpec=新的ECPrivateKeySpec(s,params);
KeyFactory KeyFactory=KeyFactory.getInstance(“EC”);
返回keyFactory.generatePrivate(privateKeySpec);
}
/**
*使用ECDH与辅因子和集成X9.63 KDF SHA-256的密钥协议
* 
*@param-ephemeralPublicey由发件人创建
*@param privateKey来自接收方
*@return包含128位AES密钥和16字节IV的32字节共享密钥
*/
私有字节[]getSharedSecret(PublicKey EpheralPublicKey,PrivateKey PrivateKey)引发异常{
String keyAgreementAlgorithm=“ECCDHwithSHA256KDF”;
KeyAgreement KeyAgreement=KeyAgreement.getInstance(keyAgreementAlgorithm,new BouncyCastleProvider());
keyAgreement.init(私钥);
keyAgreement.doPhas
javax.crypto.AEADBadTagException: Tag mismatch!

    at java.base/com.sun.crypto.provider.NativeGaloisCounterMode.decryptFinal(NativeGaloisCounterMode.java:454)