Flutter 加密 - AES 结果在 java 中不一样

问题描述 投票:0回答:1

我正在尝试解码之前在 flutter 中加密的 kotlin 中的 Uint8list,但解密不正确,我可能做错了什么但我找不到什么,你能帮我吗?

上下文:

密钥和 IV 目前是常量并且是 128 位,所以 pointyCatle 应该使用 AES128,我应该能够用相同的密钥和 IV 解密它

例子

主键 = 11112222 33344444

Uint8List mainKey = Uint8List.fromList([0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
  0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04]);
var SessionCipher=new AESEncryptor();
...
var MainCipher=new AESEncryptor();
MainCipher.setIV(SessionCipher.getIv());
MainCipher.setKey(mainKey);
var encryptedSessionKey = MainCipher.encrypt(SessionCipher.getKey());

和 iv = 00000000 00000000

data 是一个 secureRandom 生成的 Key

  • 输入:{ad,11,b4,6b,61,69,5f,e9,12,e7,05,35,b8,95,3a,09}
  • 加密输入:{0x2C, 0xC3, 0x81, 0xE9, 0x68, 0xD2, 0x83, 0x30, 0xF7, 0xA9, 0x5C, 0x4F, 0x67, 0x06, 0x3F, 0x5B}
  • 加密解密:{ad,11,b4,6b,61,69,5f,e9,12,e7,05,35,b8,95,3a,09} 好
  • javax.crypto 解密:{0x30、0xAB、0xEF、0x34、0x95、0x75、0x9D、0x96、0xE9、0x23、0x7E、0xE6、0x64、0x77、0xF4、0xD0} 坏

两者使用相同的密钥和 IV,均采用 CBC/no-padding

它可能来自使用不同算法的库吗? 我做错了什么吗?

临时Dart加密课

import 'package:ble_connect/utils/ble/FrameBuilder.dart';
import 'package:encrypt/encrypt.dart';

IV newIV() {
  // return IV.fromLength(16);
  return(IV.fromBase16("00000000000000000000000000000000"));
}

class AESEncryptor {
  var iv;
  var encrypter;
  var key;

  AESEncryptor() {
    this.key = Key.fromSecureRandom(16);
    this.iv = newIV();
    this.encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: null));
  }

  void setIV(iv) {
    this.iv = iv;
  }

  IV getIv() {
    return (this.iv);
  }

  void setKey(key) {
    this.key = key;
  }

  Key getKey() {
    return (this.key);
  }
  
  //encrypt method meant to encrypt a 128bits List or 128bits Key
  //input : data (Key or Uint8List of length 16)

  dynamic encrypt(data) {
    print("iv is : ${this.iv.base16}");
    if (data.runtimeType == Key) {
      data = toInt(combineByTwo(data.base16.split(''))); //convert a Key to a list of bytes (UGLY) 
    //additional info : data (Key) is converted to hex String by .base16 
    //then converted to list of char by .split('') 
    //then the elements of the list are grouped by two (in order to get bytes at the end ex : [f,f]-->[ff] 
    //finaly parsed to become a list of in values between 0-255
    }
    return encrypter.encryptBytes(data, iv: this.iv);
  }

}

谢谢你的帮助!

编辑: 加密库:https://github.com/leocavalcante/encrypt

Kotlin 代码

private object AES128{
    private fun cipher(opmode: Int, secretKey: ByteArray, iv: IvParameterSpec):Cipher{
        val c = Cipher.getInstance("AES/CBC/NoPadding")
        val sk = SecretKeySpec(secretKey, "AES")
        c.init(opmode, sk, iv)
        return c
    }
    fun encrypt(byteArray: ByteArray, secretKey: ByteArray, iv: IvParameterSpec): ByteArray? {
        return cipher(Cipher.ENCRYPT_MODE, secretKey, iv).doFinal(padFrame(byteArray))
    }
    fun decrypt(byteArray: ByteArray, frameDataLength: Int, secretKey: ByteArray, iv: IvParameterSpec):ByteArray?{
        return unpadFrame(cipher(Cipher.DECRYPT_MODE, secretKey, iv).doFinal(byteArray), frameDataLength)
    }

    private fun padFrame(frame: ByteArray): ByteArray {
        // MANUAL PADDING
        println(frame.size)
        val remain = (frame.size % 16).also {
            println(it)
        }
        if (remain != 0) {
            println("padding")
            val paddedValue = ByteArray(frame.size + 16 - remain)
            System.arraycopy(frame, 0, paddedValue, 0, frame.size)
            for (i in 0 until 16 - remain) {
                paddedValue[frame.size + i] = 0x0F
            }
            return paddedValue
        }
        println("not padding")
        return frame
    }

    private fun unpadFrame(frame: ByteArray, frameDataLength: Int): ByteArray {
        if(frameDataLength > 5) {
            val unpaddedValue = ByteArray(frameDataLength)
            System.arraycopy(frame, 0, unpaddedValue, 0, frameDataLength)
            return unpaddedValue
        }
        return frame
    }
}
java flutter kotlin encryption aes
1个回答
0
投票

我写了 java 和 dart 一起工作使用 AES CBC 模式 PKCS5 填充 注意 Java 中的 PKCS5 等同于 Dart 中的 PKCS7 - 它们一起工作 你可以在 java 中加密并在 Dart 中解密,反之亦然 这个 Java 部分


import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/*********this class to Encrypt and decrypt data used in sending and receiving  data**** */

public class Encryptor {

    static Encryptor instance = null;


    private Encryptor(){
        instance=this;
    }


    final static String AccKey = "ShaniaTwain2023f";
       
    public static void main(String[] args)  throws Exception{
        //() TODO Auto-generated method stub
         
          String originalString = "I like Shaina Twain Songs";
          
          byte[] ecryptedString =Encryptor.getInstance().encrypt(Encryptor.AccKey, originalString);
          String decryptedString = Encryptor.getInstance().decrypt(new String(ecryptedString) , Encryptor.AccKey) ;    
        }
     public    byte[]  encrypt (String key, String value) {
         
             String encryptString = "";
             byte[] keyBytes = new byte[16];
        
           try {
              Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //1
               SecretKeySpec keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");//2
               IvParameterSpec ivSpec = new IvParameterSpec(keyBytes); //3
               cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); //4
                encryptString = Base64.getEncoder().encodeToString(cipher.doFinal(value.getBytes("UTF-8")));//5
           
           } catch (Exception e) {
               e.printStackTrace();
           }
           return encryptString.getBytes();
            }
        public   String decrypt (String encrypted , String Key) {
            byte[] keyBytes = new byte[16];//1
            
            try {
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");//1
                SecretKeySpec skeySpec = new SecretKeySpec(Key.getBytes("UTF-8"), "AES");//2
                IvParameterSpec iv = new IvParameterSpec(keyBytes);//3
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);//4
                byte[] original = cipher.doFinal(Base64.getDecoder().decode(encrypted));//5
                    return new String(original);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

                return null;
        }
        public static Encryptor getInstance() {
            // TODO Auto-generated method stub
            if (instance==null) {
                return new Encryptor();
            }else {
                return instance;
            }
        }
}


此 Dart 部分使用 encrypt 5.0.1

import 'dart:typed_data';
import 'package:encrypt/encrypt.dart' as ency;
import 'package:flutter/material.dart';

 
class Encryptor_ {
  static final key = ency.Key.fromUtf8('ShaniaTwain2023f');
  static final iv = ency.IV.fromLength(16);
  static final encrypter =
      ency.Encrypter(ency.AES(key, mode: ency.AESMode.cbc, padding: 'PKCS7'));

  static String encrypt(plainText) {
    return encrypter.encrypt(plainText, iv: iv).base64.toString();
  }

  static String decrypt(plainText) {
    ency.Encrypted encrypted = ency.Encrypted.from64(plainText);
    return encrypter.decrypt(encrypted, iv: iv).toString();
  }
}

void main() {
  print(Encryptor_.encrypt("Hassan"));
}

© www.soinside.com 2019 - 2024. All rights reserved.