2团
Published on 2024-08-15 / 32 Visits
0
0

Java工具类对Base64解码的兼容性处理

近期处理终端连接平台编码的时候,遇到了一个有趣的问题,现进行记录。

厂商上报的加密报文需要经过Base64处理,再上传至平台进行处理。平台原先使用org.apache.tomcat.util.codec.binary.Base64工具类进行处理,函数如下所示:

    /**
     * Decodes a Base64 String into octets.
     * <p>
     * <b>Note:</b> this method only handles data encoded in standard mode.
     * </p>
     *
     * @param base64String
     *            String containing Base64 data
     * @return Array containing decoded data.
     * @since 1.4
     */
    public static byte[] decodeBase64(final String base64String) {
        return new Base64().decode(base64String);
    }

近期发现,此Base64工具类将在Tomcat11中被遗弃,故想将其替换为稳定的库函数java.util.Base64。经过简单的自测,发现两者行为一致,遂决定执行此替换操作。

但是在模拟环境,发现了意想不到的问题,厂商上报报文如下(报文长度为130):

yRd1dklHQAnAj9XpmrY3x3ZtjUS4pyTfndKH2ESScARHXMACoyJMB9jFftNbWCryI1XdLx5OscJXhUI6fCKjlxThD+G/SBNHZlMAuvT5TiRrDIpEaKtIkC7dHNxCkZKD==

执行解码操作时,报出如下异常信息:

image-zusd.png

经检查,发现是厂商上报的Base64编码不满足填充规则,以下是Base64编码的填充规则:

基本规则:  
  Base64编码将每三个字节(24位)分成四个6位的组,每个6位的组用一个Base64字符表示。
  Base64字符集包括字母A-Z、a-z、数字0-9、加号(+)和斜杠(/)。
填充字符:  
  如果输入数据的字节数不是3的倍数,则需要在编码后的字符串末尾添加一个或两个等号(=)作为填充字符。
  1个字节的输入数据将产生2个Base64字符,并添加2个等号(==)。
  2个字节的输入数据将产生3个Base64字符,并添加1个等号(=)。
示例:  
  输入数据"Man"(3个字节)编码为"TWFu"(不需要填充)。
  输入数据"Ma"(2个字节)编码为"TWE="(需要1个填充字符)。
  输入数据"M"(1个字节)编码为"TQ=="(需要2个填充字符)。

有趣的点在于,在处理异常填充时,java.util.Base64会抛出解码异常,而org.apache.tomcat.util.codec.binary.Base64工具类会选择尽可能返回能解码的字符串。

考虑到现在有较多的终端已经售出,现阶段选择保留org.apache.tomcat.util.codec.binary.Base64工具类进行解码,待后续完善。


Comment