无法从Java在iOS(Swift)中解密(AES)

时间:2019-05-23 10:07:27

标签: java ios swift encryption aes

我无法在从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());
        }

1 个答案:

答案 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
    }
}