密码技术学习(9)-邮件传输算法(Base64)

版权声明:转载请注明出处 https://blog.csdn.net/laozhaishaozuo/article/details/82287321
  • 什么是Base64算法
  • Base64算法的应用
  • Java中使用Base64算法

什么是Base64算法

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法.百度百科

在早期,Base64编码算法主要是为了解决电子邮件传送问题。在某些很古老的邮件服务器只支持ASCII码字符,对于非ASCII码字符可能做调整将最高位置0,造成乱码。为了解决该问题诞生了Base64编码。

编码表

编码表如下


                    Table 1: The Base64 Alphabet

     Value Encoding  Value Encoding  Value Encoding  Value Encoding
         0 A            17 R            34 i            51 z
         1 B            18 S            35 j            52 0
         2 C            19 T            36 k            53 1
         3 D            20 U            37 l            54 2
         4 E            21 V            38 m            55 3
         5 F            22 W            39 n            56 4
         6 G            23 X            40 o            57 5
         7 H            24 Y            41 p            58 6
         8 I            25 Z            42 q            59 7
         9 J            26 a            43 r            60 8
        10 K            27 b            44 s            61 9
        11 L            28 c            45 t            62 +
        12 M            29 d            46 u            63 /
        13 N            30 e            47 v
        14 O            31 f            48 w         (pad) =
        15 P            32 g            49 x
        16 Q            33 h            50 y

Base64Url与其类似,不过最后两位不同


         Table 2: The "URL and Filename safe" Base 64 Alphabet

     Value Encoding  Value Encoding  Value Encoding  Value Encoding
         0 A            17 R            34 i            51 z
         1 B            18 S            35 j            52 0
         2 C            19 T            36 k            53 1
         3 D            20 U            37 l            54 2
         4 E            21 V            38 m            55 3
         5 F            22 W            39 n            56 4
         6 G            23 X            40 o            57 5
         7 H            24 Y            41 p            58 6
         8 I            25 Z            42 q            59 7
         9 J            26 a            43 r            60 8
        10 K            27 b            44 s            61 9
        11 L            28 c            45 t            62 - (minus)
        12 M            29 d            46 u            63 _
        13 N            30 e            47 v           (underline)
        14 O            31 f            48 w
        15 P            32 g            49 x
        16 Q            33 h            50 y         (pad) =

算法

经过Base64编码之后,密码长度变为了原来的4/3倍。
具体算法如下:
1. 将对应的字符串以字符为单位,转换为对应的字符编码
2. 将获得的字符编码转化为二进制
3. 将获得的二进制码每3个8位二进制为一组,转换为每4个6位二进制一组,3*8=4*6,如果最后一组不够3个,则最终结果将会添加一个或两个 (pad) =
4. 将获得的6位二进制高位补0,成为8进制,变为4个8位二进制一组
5. 将4个8位二进制转换为10进制码
6. 在上述转换表中找到对应的字符

举个例子

内存1个字节占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组) 011100 110011 000100 110011
然后计算机是88位的存数 6不够,自动就补两个高位0了
所有有了 高位补000011100 00110011 00000100 00110011
得到 28 51 4 51
查对下照表 c z E z

如果最终转码之后,不够4位,则以=代替

转前:A
先转成ascii:对应 65
2进制: 01000001
6个一组(2组): 010000 01
不够6位补零:010000 010000
高位补000010000 00010000
得到 16 16
查对下照表:QQ
最终结果:QQ==

Base64算法的应用

Base64算法有很多用途
1. 用于邮件传输
2. 用于网络数据传输,比如说图片
3. 数字证书存储
4. 密钥存储

Java中使用Base64算法

对于Base64这种常用算法,Jdk直到1.8之后才增加。
我们可以使用Java来验证,上文中的例子

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.util.Arrays;

import org.junit.Test;

import com.google.common.base.Charsets;

public class Base64Test {

    @Test
    public void testBase64() throws IOException {
        byte[] data = new String("s13").getBytes(Charsets.UTF_8);
        System.out.println(Arrays.toString(data));
        for (byte i : data) {
            System.out.println(Integer.toBinaryString(i));
        }
        System.out.println(new String(data));
        byte[] result = org.bouncycastle.util.encoders.Base64.encode(data);
        byte[] jdkBase = java.util.Base64.getEncoder().encode(data);
        assertEquals(Arrays.toString(result), Arrays.toString(jdkBase));
        System.out.println(Arrays.toString(jdkBase));
        System.out.println(new String(result));
    }

    @Test
    public void testA() throws IOException {
        byte[] data = new String("A").getBytes(Charsets.UTF_8);
        System.out.println(Arrays.toString(data));
        for (byte i : data) {
            System.out.println(Integer.toBinaryString(i));
        }
        System.out.println(new String(data));
        byte[] result = org.bouncycastle.util.encoders.Base64.encode(data);
        byte[] jdkBase = java.util.Base64.getEncoder().encode(data);
        assertEquals(Arrays.toString(result), Arrays.toString(jdkBase));
        System.out.println(Arrays.toString(jdkBase));
        System.out.println(new String(result));
    }

}

参考资料

  1. Java加密与解密的艺术 链接
  2. 数字签名算法 百度百科
  3. RFC2045
  4. RFC2045

本系列其他文章

密码技术学习系列文章

猜你喜欢

转载自blog.csdn.net/laozhaishaozuo/article/details/82287321