黑色毛嗑儿 发表于 2023-5-19 12:46:40

请教安卓版AES-ECB加密输出结果错误

安卓版AES-ECB加密和PC版输出结果不一样怎么回事,也和其它在线加密不一样,均已转换16进制文本相比较的。明文:“12345678”,密钥:“1234567812345678”,pc版的正确,安卓版就不对,想不通了,请大神赐教!

黑色毛嗑儿 发表于 2023-5-19 12:50:02

第一张为电脑版,第二张安卓版

黑色毛嗑儿 发表于 2023-5-19 12:52:29

黑色毛嗑儿 发表于 2023-5-19 12:50
第一张为电脑版,第二张安卓版

图片怎么传不上去

howill2021 发表于 2023-5-19 20:56:53

<火山程序 类型 = "通常" 版本 = 1 />

类 AES加解密通用类 <公开 注释 = "★ 本类由\"飞翔的企鹅\"封装.">
{
    方法 加密 <公开 静态 类型 = 文本型 注释 = "AES是一种对称加密方法,即:加解密过程中使用相同的一个密码(密钥)来进行."
            返回值注释 = "返回加密后的数据,如果加密失败或提供所需参数不正确将返回空对象." 返回值注释 = "注意:返回的结果是使用Base64编码后的结果." @禁止流程检查 = 真>
    参数 欲加密数据 <类型 = 文本型 注释 = "提供所欲加密的数据.">
    参数 密码 <类型 = 文本型 注释 = "提供所欲使用的密码文本." 注释 = "注意:该方法并未使用强随机种子算法处理密钥,即所提供的密码必须是以下长度(如非以下长度将加密失败):"
            注释 = "16字节,24字节或32字节长度.">
    参数 偏移 <类型 = 文本型 注释 = "提供加密欲使用的偏移数据,ECB模式无需偏移." @默认值 = 空对象>
    参数 模式及填充方式 <类型 = 文本型 注释 = "注意:此处如果不懂填充模式以及加密模式的请保持该参数默认值."
            注释 = "如果格式提供不正确(或与加密方法使用的不一致)将无法正常解密,请严格按照以下列举出的模式进行本参数的提供."
            注释 = "参数格式形如(ECB加密模式无填充):\"ECB/NoPadding\"." 注释 = "加密模式/填充方式支持所需的API等级"
            注释 = "\"CBC/ISO10126Padding\"API1+" 注释 = "\"CBC/NoPadding\"API1+"
            注释 = "\"CBC/PKCS5Padding\"API1+" 注释 = "" 注释 = "\"CFB/ISO10126Padding\"API1+"
            注释 = "\"CFB/NoPadding\"API1+" 注释 = "\"CFB/PKCS5Padding\"API1+" 注释 = ""
            注释 = "\"CTR/ISO10126Padding\"API1+" 注释 = "\"CTR/NoPadding\"API1+"
            注释 = "\"CTR/PKCS5Padding\"API1+" 注释 = "" 注释 = "\"CTS/ISO10126Padding\"API1+"
            注释 = "\"CTS/NoPadding\"API1+" 注释 = "\"CTS/PKCS5Padding\"API1+" 注释 = ""
            注释 = "\"ECB/ISO10126Padding\"API1+" 注释 = "\"ECB/NoPadding\"API1+"
            注释 = "\"ECB/PKCS5Padding\"API1+" 注释 = "" 注释 = "\"OFB/ISO10126Padding\"API1+"
            注释 = "\"OFB/NoPadding\"API1+" 注释 = "\"OFB/PKCS5Padding\"API1+" 注释 = ""
            注释 = "\"GCM/NoPadding\"API10+" 折叠2 @默认值 = 空对象>
    参数 编码类型 <类型 = 文本型 注释 = "加密结果所欲使用的编码类型." @默认值 = "UTF-8">
    {
      如果 (文本是否为空 (欲加密数据) || 密码 == 空对象 || 文本是否为空 (密码))
      {
            返回 (空对象)
      }
      变量 模式 <类型 = 文本型>
      如果 (模式及填充方式 != 空对象 && 文本是否为空 (模式及填充方式) == 假)
      {
            模式 = "AES/" + 模式及填充方式
      }
      否则
      {
            模式 = "AES/ECB/NoPadding"
      }
      开始俘获异常 ()
      {
            @ javax.crypto.spec.SecretKeySpec secretKeySpec = new javax.crypto.spec.SecretKeySpec(@<密码>.getBytes(), "AES");
            @ javax.crypto.spec.IvParameterSpec ivParameterSpec = new javax.crypto.spec.IvParameterSpec(@<偏移>.getBytes());
            @ javax.crypto.Cipher instance = javax.crypto.Cipher.getInstance(@<模式>);
            @ instance.init(1, secretKeySpec, ivParameterSpec);
            @ return new String(android.util.Base64.encode(instance.doFinal(@<欲加密数据>.getBytes()), 2), @<编码类型>);
      }
      俘获所有异常 ()
      {
            返回 (空对象)
      }
    }

    方法 解密 <公开 静态 类型 = 文本型 注释 = "AES是一种对称加密方法,即:加解密过程中使用相同的一个密码(密钥)来进行." @禁止流程检查 = 真>
    参数 欲解密数据 <类型 = 文本型 注释 = "提供所欲解密的Base64编码数据.">
    参数 密码 <类型 = 文本型 注释 = "提供所欲使用的密码文本." 注释 = "注意:该方法并未使用强随机种子算法处理密钥,即所提供的密码必须是以下长度(如非以下长度将解密失败):"
            注释 = "16字节,24字节或32字节长度." 折叠2>
    参数 偏移 <类型 = 文本型 注释 = "提供解密欲使用的偏移数据,ECB模式无需偏移." @默认值 = 空对象>
    参数 模式及填充方式 <类型 = 文本型 注释 = "注意:此处如果不懂填充模式以及加密模式的请保持该参数默认值."
            注释 = "如果格式提供不正确(或与加密方法使用的不一致)将无法正常解密,请严格按照以下列举出的模式进行本参数的提供."
            注释 = "参数格式形如(ECB加密模式无填充):\"ECB/NoPadding\"." 注释 = "加密模式/填充方式支持所需的API等级"
            注释 = "\"CBC/ISO10126Padding\"API1+" 注释 = "\"CBC/NoPadding\"API1+"
            注释 = "\"CBC/PKCS5Padding\"API1+" 注释 = "" 注释 = "\"CFB/ISO10126Padding\"API1+"
            注释 = "\"CFB/NoPadding\"API1+" 注释 = "\"CFB/PKCS5Padding\"API1+" 注释 = ""
            注释 = "\"CTR/ISO10126Padding\"API1+" 注释 = "\"CTR/NoPadding\"API1+"
            注释 = "\"CTR/PKCS5Padding\"API1+" 注释 = "" 注释 = "\"CTS/ISO10126Padding\"API1+"
            注释 = "\"CTS/NoPadding\"API1+" 注释 = "\"CTS/PKCS5Padding\"API1+" 注释 = ""
            注释 = "\"ECB/ISO10126Padding\"API1+" 注释 = "\"ECB/NoPadding\"API1+"
            注释 = "\"ECB/PKCS5Padding\"API1+" 注释 = "" 注释 = "\"OFB/ISO10126Padding\"API1+"
            注释 = "\"OFB/NoPadding\"API1+" 注释 = "\"OFB/PKCS5Padding\"API1+" 注释 = ""
            注释 = "\"GCM/NoPadding\"API10+" 折叠2 @默认值 = 空对象>
    参数 编码类型 <类型 = 文本型 注释 = "指定加密数据所使用的编码类型." @默认值 = "UTF-8">
    {
      如果 (文本是否为空 (欲解密数据) || 密码 == 空对象 || 文本是否为空 (密码))
      {
            返回 (空对象)
      }
      变量 模式 <类型 = 文本型>
      如果 (模式及填充方式 != 空对象 && 文本是否为空 (模式及填充方式) == 假)
      {
            模式 = "AES/" + 模式及填充方式
      }
      否则
      {
            模式 = "AES/ECB/NoPadding"
      }
      开始俘获异常 ()
      {
            @ byte[] bytes = android.util.Base64.decode(@<欲解密数据>, 2);
            @ javax.crypto.spec.SecretKeySpec secretKeySpec = new javax.crypto.spec.SecretKeySpec(@<密码>.getBytes(), "AES");
            @ javax.crypto.spec.IvParameterSpec ivParameterSpec = new javax.crypto.spec.IvParameterSpec(@<偏移>.getBytes());
            @ javax.crypto.Cipher instance = javax.crypto.Cipher.getInstance(@<模式>);
            @ instance.init(2, secretKeySpec, ivParameterSpec);
            @ return new String(instance.doFinal(bytes), @<编码类型>);
      }
      俘获所有异常 ()
      {
            返回 (空对象)
      }
    }
}


我记得有2个AES库,可以试一下,也可以复制这段试一下

黑色毛嗑儿 发表于 2023-5-22 20:46:03

就是用的这个结果不对

黑色毛嗑儿 发表于 2023-5-27 19:14:04

已经修复了,修改了封装的嵌入代码,已经可以正常显示结果了

黑色毛嗑儿 发表于 2023-5-28 10:17:29

根据网上java代码修改了一下,ECB无偏移,所有移出了这个参数,稍后把源码发上来,大神给解释一下

黑色毛嗑儿 发表于 2023-5-28 13:40:49

类定义部分:

<火山程序 类型 = "通常" 版本 = 1 />

类 AES_ECB加密解密类 <公开>
{
    方法 加密 <公开 静态 类型 = "字节 []" 注释 = "AES是一种对称加密方法,即:加解密过程中使用相同的一个密码(密钥)来进行"
            返回值注释 = "返回加密后的数据,如果加密失败或提供所需参数不正确将返回空对象." @禁止流程检查 = 真>
    参数 欲加密数据 <类型 = 文本型 注释 = "提供所欲加密的数据.">
    参数 密码 <类型 = 文本型 注释 = "提供所欲使用的密码数据." 注释 = "注意:该方法并未使用强随机种子算法处理密钥,即所提供的密码必须是以下长度(如非以下长度将加密失败):"
            注释 = "16字节,24字节或32字节长度">
    参数 模式及填充方式 <类型 = 文本型 注释 = "注意:此处如果不懂填充模式以及加密模式的请保持该参数默认值."
            注释 = "如果格式提供不正确(或与加密方法使用的不一致)将无法正常解密,请严格按照以下列举出的模式进行本参数的提供." 注释 = "参数格式形如(ECB加密模式无填充):\"ECB/NoPadding\"." 注释 = "加密模式/填充方式支持所需的API等级"
            @默认值 = 空对象>
    参数 编码类型 <类型 = 文本型 @默认值 = "UTF-8">
    {
      变量 返回数据 <类型 = "字节 []">
      变量 模式 <类型 = 文本型>

      如果 (欲加密数据 == 空对象 || 密码 == 空对象)
      {
            返回 (空对象)
      }
      否则
      {
            如果 (模式及填充方式 != 空对象 && 文本是否为空 (模式及填充方式) == 假)
            {
                模式 = "AES/" + 模式及填充方式
            }
            否则
            {
                模式 = "AES/ECB/NoPadding"
            }

            @ @m<RUN_E>(
            @      javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(@<模式>); //"算法/模式/补码方式"
            @      cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, new javax.crypto.spec.SecretKeySpec(@<密码>.getBytes(@<编码类型>), "AES"));      
            @      @<返回数据> = cipher.doFinal(@<欲加密数据>.getBytes(@<编码类型>));
            @ )
            返回 (返回数据)
      }
    }

    #

    方法 解密 <公开 静态 类型 = 文本型 注释 = "AES是一种对称加密方法,即:加解密过程中使用相同的一个密码(密钥)来进行." 返回值注释 = "失败返回空对象" @禁止流程检查 = 真>
    参数 欲解密数据 <类型 = "字节 []" 注释 = "提供所欲解密的密码数据.">
    参数 密码 <类型 = 文本型 注释 = "提供所欲使用的密码数据." 注释 = "注意:该方法并未使用强随机种子算法处理密钥,即所提供的密码必须是以下长度(如非以下长度将解密失败):"
            注释 = "16字节,24字节或32字节长度.">
    参数 模式及填充方式 <类型 = 文本型 注释 = "注意:此处如果不懂填充模式以及加密模式的请保持该参数默认值."
            注释 = "如果格式提供不正确(或与加密方法使用的不一致)将无法正常解密,请严格按照以下列举出的模式进行本参数的提供."
            注释 = "参数格式形如(ECB加密模式无填充):\"ECB/NoPadding\"." 注释 = "加密模式/填充方式支持所需的API等级"
             @默认值 = 空对象>
    参数 编码类型 <类型 = 文本型 @默认值 = "UTF-8">
    {
      变量 返回数据 <类型 = 文本型>
      变量 解码数据 <类型 = "字节[]">
      变量 原始数据 <类型 = "字节 []">
      变量 模式 <类型 = 文本型>

      如果 (欲解密数据 == 空对象 || 密码 == 空对象)
      {
            返回 (空对象)
      }
      否则
      {
            如果 (模式及填充方式 != 空对象 && 文本是否为空 (模式及填充方式) == 假)
            {
                模式 = "AES/" + 模式及填充方式
            }
            否则
            {
                模式 = "AES/ECB/NoPadding"
            }
            @ @m<RUN_E>(
            @       javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(@<模式>); //"算法/模式/补码方式"
            @       cipher.init(javax.crypto.Cipher.DECRYPT_MODE, new javax.crypto.spec.SecretKeySpec(@<密码>.getBytes(@<编码类型>), "AES"));
            @       @<解码数据> = android.util.Base64.decode(@<欲解密数据>, 2);//先用base64解码
            @       @<原始数据> = cipher.doFinal(@<解码数据>);
            @       @<返回数据> = new String(@<原始数据>, @<编码类型>);
            @ )
            返回 (返回数据)
      }

      {

      }
    }
}


加密解密调用实现部分:

<火山程序 类型 = "通常" 版本 = 1 />

变量 加密结果 <类型 = "字节 []">

加密结果 = AES_ECB加密解密类.加密 ("12345678", "1234567812345678", "ECB/PKCS5Padding")
编辑框_内容.内容 = Base64类.编码至文本 (加密结果)

<火山程序 类型 = "通常" 版本 = 1 />

变量 解密结果 <类型 = 文本型>

解密结果 = AES_ECB加密解密类.解密 (文本到字节数组 (编辑框_内容.内容), "1234567812345678") //这里解密完是文本就不要再Base64编码了
提示框 ("解密结果:" + 解密结果)
结果为:2jbNzsip7gCp63A+R43tEQ==
结果正确了,不管哪一种都能加密和解密,但这种是我想要的,有个APP请求数据就是这样的,逆向到私钥了,可以模拟post登录了





页: [1]
查看完整版本: 请教安卓版AES-ECB加密输出结果错误