我无法在从Java服务器获取的iOS(Swift)上解密数据。但是,如果我在iOS上加密数据然后解密,则效果很好。双方的AES代码可能存在一些无法识别的差异。请帮我。
类似的问题在这里问:https://github.com/krzyzanowskim/CryptoSwift/issues/458
iOS解密器
let password = "SOME_ENCRYPTION_KEY"
let iv = AES256Crypter.randomIv()
let key = try AES256Crypter.createKey(password: password.data(using: .utf8)!, salt: salt)
let aes = try AES256Crypter(key: key, iv: iv)
let encryptedData = "encrypted_data".data(using: .utf8)
let decryptedData = try aes.decrypt(encryptedData!)
let decryptedString = String(decoding: decryptedData, as: UTF8.self)
print("Decrypted string: \(decryptedString)")
Java加密器
SecretKeySpec secretKey;
try {
byte[] key = ENCRYPTION_KEY.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
} catch (Exception e) {
System.out.println("\nException while encrypting " + strToEncrypt + " \nerror: " + e.getMessage());
}
答案 0 :(得分:0)
下面是 Java加密的代码 和用于iOS的解密(Swift和Android(Kotlin))。这很好,但我仍然愿意寻求更好的解决方案。
Java代码
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
public class EncryptionUtils {
private static String ENCRYPTION_KEY = "1234512345123456";
public static void main(String[] args) {
String encyString = new EncryptionUtils().encrypted("HJUSER153");
System.out.println("Encrypted String:" + encyString);
}
public String encrypted(String strToEncrypt) {
try {
IvParameterSpec ivspec = new IvParameterSpec(ENCRYPTION_KEY.getBytes());
SecretKeySpec keyspec = new SecretKeySpec(ENCRYPTION_KEY.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
//encrypted = cipher.doFinal(text.getBytes());
} catch (Exception e) {
System.out.println("\nException while encrypting " + strToEncrypt + " \nerror: " + e.getMessage());
}
return null;
}
}
iOS Swift代码
将此添加到pod文件中- pod'CryptoSwift'
import CryptoSwift
func decrypt(input:String)->String?{
let key = "1234512345123456"
do{
let d=Data(base64Encoded: input)
let decrypted = try AES(key: key, iv: key, padding: .pkcs5).decrypt(
d!.bytes)
return String(data: Data(decrypted), encoding: .utf8)
}catch{
}
return nil
}
Android
import android.util.Base64
import java.security.NoSuchAlgorithmException
import javax.crypto.Cipher
import javax.crypto.NoSuchPaddingException
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
class CypherHelper {
private var ivspec: IvParameterSpec? = null
private var keyspec: SecretKeySpec? = null
private var cipher: Cipher? = null
private val ENCRYPTION_KEY: String = "1234567890123456"
init {
ivspec = IvParameterSpec(ENCRYPTION_KEY.toByteArray(Charsets.UTF_8))
keyspec = SecretKeySpec(ENCRYPTION_KEY.toByteArray(), "AES")
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
} catch (e: NoSuchAlgorithmException) {
e.printStackTrace()
} catch (e: NoSuchPaddingException) {
e.printStackTrace()
}
}
fun decrypt(valueToDecrypt: String): String {
var decryptValue: String = ""
val enc = CypherHelper()
if (valueToDecrypt.isEmpty())
decryptValue = String(enc.decryptInternal(valueToDecrypt)!!)
return decryptValue
}
private fun decryptInternal(code: String?): ByteArray? {
if (code == null || code.isEmpty()) {
throw Exception("Empty string")
}
var decrypted: ByteArray? = null
try {
cipher?.init(Cipher.DECRYPT_MODE, keyspec, ivspec)
decrypted = cipher?.doFinal(Base64.decode(code, Base64.DEFAULT))
} catch (e: Exception) {
throw Exception("[decrypt] " + e.message)
}
return decrypted
}
}