【发布时间】:2021-04-18 07:06:28
【问题描述】:
我打算在iOS和Android用ECC加密,在server端解密。iOS用objective-C,Android和Server用Java。iOS用CryptopECChttps://github.com/SandeepAggarwal/CryptoppECC,加解密都能成功。服务器也可以使用Java成功加解密。但是,当我在服务器上解密IOS的加密数据时,它会失败。 iOS:
- (void)eccCryptForShortKey{
NSString *publicKey = @"AvWy7WANZcn0ea1Li2AJCjo=";
NSString *privateKey = @"ANqNuiMahQziTilCGa2bA3A=";
NSString *str = @"hello world";
CurveType curveType = CurveType_secp128r1;
CryptoppECC *ecc = [[CryptoppECC alloc] init];
// encrypt
NSString *enStr =[ecc encrypt:str :publicKey curve:curveType];
// decrypt
NSString*deStr = [ecc decrypt:enStr :privateKey curve:curveType];
if (deStr.length == 0) {
NSLog(@"\n===Fail");
}else{
NSLog(@"\n===Succ: %@",deStr);
}
}
Java:
public class EccCryptopp{
public static final String curve = "secp128r1";
private static final String CIPHER = "ECIES";
private static final String ALGRITHM = "ECDSA";
private static final String PROVIDER = "BC";
private static final String publicKeyStrShort = "AvWy7WANZcn0ea1Li2AJCjo=";
private static final String privateKeyStrShort = "ANqNuiMahQziTilCGa2bA3A=";
static{
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}
public static void test() {
//the data encrypted in iOS
String encryptData = "BO1QGnFjDNVQ3rmcVhKJDZuYJl427Pbgt2lv9PvQ3ifXwDjKG/XcdqG5Mu1FEVahifhyXrtQEgvDUP1T0kjk0w==";
String decryptData = decryptDataWithShortKey(encryptData, privateKeyStrShort);
int dLength = decryptData.length();
if (dLength == 0) {
System.out.println("decrypt fail");
} else {
System.out.println("decrypt data:" + dLength);
System.out.println(decryptData);
}
}
private static byte[] base64Decode(String s){
return Base64.getDecoder().decode(s);
}
public static PublicKey loadPublicKeyWithShort(String curve, byte[] data)
throws GeneralSecurityException {
KeyFactory factory = KeyFactory.getInstance(ALGRITHM, PROVIDER);
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curve);
ECCurve eccCurve = spec.getCurve();
EllipticCurve ellipticCurve = EC5Util.convertCurve(eccCurve, spec.getSeed());
java.security.spec.ECPoint point = ECPointUtil.decodePoint(ellipticCurve, data);
java.security.spec.ECParameterSpec params = EC5Util.convertSpec(ellipticCurve, spec);
ECPublicKeySpec keySpec = new ECPublicKeySpec(point, params);
return factory.generatePublic(keySpec);
}
public static PrivateKey loadPrivateKeyWithShort(String curve, byte[] data)
throws GeneralSecurityException {
KeyFactory factory = KeyFactory.getInstance(ALGRITHM, PROVIDER);
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curve);
ECCurve eccCurve = spec.getCurve();
EllipticCurve ellipticCurve = EC5Util.convertCurve(eccCurve, spec.getSeed());
java.security.spec.ECParameterSpec params = EC5Util.convertSpec(ellipticCurve, spec);
ECPrivateKeySpec keySpec = new ECPrivateKeySpec(new BigInteger(1, data), params);
return factory.generatePrivate(keySpec);
}
public static String encryptDataWithShortKey(String token, String publicKeyShort) {
try {
PublicKey publicKey = loadPublicKeyWithShort(curve, base64Decode(publicKeyShort));
Cipher c = Cipher.getInstance(CIPHER);
c.init(Cipher.ENCRYPT_MODE, publicKey);
String messageString = token;
byte[] message = messageString.getBytes();
byte[] cipher = c.doFinal(message);
return Base64.getEncoder().encodeToString(cipher);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decryptDataWithShortKey(String message,String private_key) {
try {
PrivateKey privateKey = loadPrivateKeyWithShort(curve, base64Decode(private_key));
Cipher c = Cipher.getInstance(CIPHER);
byte[] token = ((Base64.getDecoder().decode(message.getBytes())));
c.init(Cipher.DECRYPT_MODE, privateKey);
byte[] plaintext = c.doFinal(token);
return new String(plaintext);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.58</version>
</dependency>
获取IOS的加密内容并解密时,总是异常。 enter image description here
org.bouncycastle.jcajce.provider.util.BadBlockException: unable to process block
at org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.engineDoFinal(Unknown Source)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2207)
at com.nonce.crypto.ecc.EccCryptopp.decryptDataWithShortKey(EccCryptopp.java:165)
at com.nonce.crypto.ecc.EccCryptopp.test(EccCryptopp.java:59)
at com.nonce.crypto.ecc.ECC.testEccCryptopp(ECC.java:38)
at com.nonce.crypto.ecc.ECC.main(ECC.java:23)
Caused by: org.bouncycastle.crypto.InvalidCipherTextException: invalid MAC
at org.bouncycastle.crypto.engines.IESEngine.decryptBlock(Unknown Source)
at org.bouncycastle.crypto.engines.IESEngine.processBlock(Unknown Source)
... 6 more
不知道是Java解密还是IOS加密。
【问题讨论】: