Kotlin AES解密 Dart AES加密的数据报错

Decrypting Dart AES encrypted data in Kotlin results in BadPaddingException

Dart加密代码

import 'dart:convert';
import 'dart:typed_data';

import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart';

class CryptoService {
  static String encryptString(String input) {
    const keyString = "ABCdefg1234!!";
    final keyBytes = sha256.convert(utf8.encode(keyString)).bytes;
    final key = Key(Uint8List.fromList(keyBytes));
    final iv = IV.fromSecureRandom(16);
    final encrypter = Encrypter(AES(key));

    final encrypted = encrypter.encrypt(input, iv: iv);
    final combined = iv.bytes + encrypted.bytes;

    return base64Url.encode(combined);
  }

  static String decryptString(String encoded) {
    const keyString = "ABCdefg1234!!";
    final keyBytes = sha256.convert(utf8.encode(keyString)).bytes;
    final key = Key(Uint8List.fromList(keyBytes));
    final encrypter = Encrypter(AES(key));

    final combinedBytes = base64Url.decode(encoded);
    final ivBytes = combinedBytes.sublist(0, 16);
    final encryptedBytes = combinedBytes.sublist(16);

    final iv = IV(Uint8List.fromList(ivBytes));
    final encrypted = Encrypted(encryptedBytes);
    final decrypted = encrypter.decrypt(encrypted, iv: iv);

    return decrypted;
  }
}

void main() {
  print(CryptoService.encryptString("abcdef"));
}

Kotlin解密代码

import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.util.*
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import java.security.SecureRandom

object CryptoService {
    private const val keyString = "ABCdefg1234!!"

    private fun generateKey(): SecretKey {
        val keyBytes = MessageDigest.getInstance("SHA-256").digest(keyString.toByteArray(StandardCharsets.UTF_8))
        return SecretKeySpec(keyBytes, "AES")
    }

    fun encryptString(input: String): String {
        val key = generateKey()
        val iv = ByteArray(16).apply { SecureRandom().nextBytes(this) }
        val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding").apply {
            init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(iv))
        }
        val encryptedBytes = cipher.doFinal(input.toByteArray(StandardCharsets.UTF_8))
        val combined = iv + encryptedBytes
        return Base64.getUrlEncoder().encodeToString(combined)
    }

    fun decryptString(encoded: String): String {
        val key = generateKey()
        val combinedBytes = Base64.getUrlDecoder().decode(encoded)
        val iv = combinedBytes.sliceArray(0 until 16)
        val encryptedBytes = combinedBytes.sliceArray(16 until combinedBytes.size)
        val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding").apply {
            init(Cipher.DECRYPT_MODE, key, IvParameterSpec(iv))
        }
        val decryptedBytes = cipher.doFinal(encryptedBytes)
        return String(decryptedBytes, StandardCharsets.UTF_8)
    }
}


fun main() {
   println(CryptoService.decryptString("FzaO3XI3ZVtUDAdM1So357dhQwg37fh0vzVr6jkPDaY="))

   println("end")
}

报错如下:

Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
 at com.sun.crypto.provider.CipherCore.unpad (:-1) 
 at com.sun.crypto.provider.CipherCore.fillOutputBuffer (:-1) 
 at com.sun.crypto.provider.CipherCore.doFinal (:-1) 

解决:

kotlin解密部分改为如下代码:

import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.util.*
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import java.security.SecureRandom
import org.bouncycastle.jce.provider.BouncyCastleProvider
import javax.crypto.SecretKey

object CryptoService {
    private const val keyString = "ABCdefg1234!!"

    init {
        Security.addProvider(BouncyCastleProvider())
    }
    // 此处是关键代码
    private fun generateKey(): SecretKey {
        val keyBytes = MessageDigest.getInstance("SHA-256").digest(keyString.toByteArray(StandardCharsets.UTF_8))
        return SecretKeySpec(keyBytes, "AES")
    }

    fun encryptString(input: String): String {
        val key = generateKey()
        val iv = ByteArray(16).apply { SecureRandom().nextBytes(this) }
        val cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "BC").apply {
            init(Cipher.ENCRYPT_MODE, key, IvParameterSpec(iv))
        }
        val encryptedBytes = cipher.doFinal(input.toByteArray(StandardCharsets.UTF_8))
        val combined = iv + encryptedBytes
        return Base64.getUrlEncoder().encodeToString(combined)
    }

    fun decryptString(encoded: String): String {
        val key = generateKey()
        val combinedBytes = Base64.getUrlDecoder().decode(encoded)
        val iv = combinedBytes.sliceArray(0 until 16)
        val encryptedBytes = combinedBytes.sliceArray(16 until combinedBytes.size)
        val cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "BC").apply {
            init(Cipher.DECRYPT_MODE, key, IvParameterSpec(iv))
        }
        val decryptedBytes = cipher.doFinal(encryptedBytes)
        return String(decryptedBytes, StandardCharsets.UTF_8)
    }
}


fun main() {
   println(CryptoService.decryptString("FzaO3XI3ZVtUDAdM1So357dhQwg37fh0vzVr6jkPDaY="))

   println("end")
}
k中有很多加密解密库可以使用。其中一些常用的库包括: 1. Java Cryptography Extension (JCE):Java的标准加密解密库,可以在Kotlin中使用。 2. Bouncy Castle: 一个开源的加密库,支持多种加密算法和协议。 3. Kotlin Crypto: 一个基于Kotlin语言的轻量级加密库,提供了对常见加密算法的支持。 4. Tink: 由Google开发的一个现代化的加密库,支持各种加密操作和安全功能。 以下是使用Kotlin Crypto库进行加密解密的示例代码: ```kotlin import org.bouncycastle.jce.provider.BouncyCastleProvider import org.bouncycastle.util.encoders.Base64 import javax.crypto.Cipher import javax.crypto.spec.SecretKeySpec fun encrypt(input: String, password: String): String { val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", BouncyCastleProvider()) val keySpec = SecretKeySpec(password.toByteArray(), "AES") cipher.init(Cipher.ENCRYPT_MODE, keySpec) val encryptedBytes = cipher.doFinal(input.toByteArray()) return Base64.toBase64String(encryptedBytes) } fun decrypt(input: String, password: String): String { val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", BouncyCastleProvider()) val keySpec = SecretKeySpec(password.toByteArray(), "AES") cipher.init(Cipher.DECRYPT_MODE, keySpec) val decryptedBytes = cipher.doFinal(Base64.decode(input)) return String(decryptedBytes) } fun main(args: Array<String>) { val input = "欢迎来到Errol_King的博客" val password = "12345678" val encrypt = encrypt(input, password) println(encrypt) val decrypt = decrypt(encrypt, password) println(decrypt) } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值