1 需求描述
将字符串helloworld
使用SHA-256和BASE64算法进行加密。
2 实验过程
2.1 Power shell加密操作
Step1 首先将helloworld
写在桌面新建的txt文件中,并且复制路径。
Step2 打开PowerShell,输入以下命令,开始计算SHA-256:
Get-FileHash "C:UsersLenovoOneDrive桌面sha256.txt"
Step3 返回SHA-256的计算结果,复制该结果。
代码语言:javascript复制Algorithm Hash Path
--------- ---- ----
SHA256 936A185CAAA266BB9CBE981E9E05CB78CD732B0B3280EB944412BB6F8F8F07AF C:UsersLenovoOneDrive桌面...
Step4 复制的SHA-256计算结果粘贴至该命令括号内,开始计算BASE64:
代码语言:javascript复制[Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes('936A185CAAA266BB9CBE981E9E05CB78CD732B0B3280EB944412BB6F8F8F07AF'))
Step5 得出BASE64值:
代码语言:javascript复制OTM2QTE4NUNBQUEyNjZCQjlDQkU5ODFFOUUwNUNCNzhDRDczMkIwQjMyODBFQjk0NDQxMkJCNkY4RjhGMDdBRg==
2.2 Java加密操作
代码语言:javascript复制package org.example;
import sun.misc.BASE64Encoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Main {
public static void main(String[] args) {
MessageDigest sha256 = null;
try {
String content = "helloworld";
// 先对helloworld进行 SHA256 加密
sha256 = MessageDigest.getInstance("SHA-256");
byte[] hash = sha256.digest(content.getBytes(StandardCharsets.UTF_8));
// 再对加密后的二进制数组进行 BASE64 加密
BASE64Encoder base64 = new BASE64Encoder();
String result = base64.encode(hash);
// 将二进制SHA-256转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
String str16 = hexString.toString();
// 十六进制hash进行base64加密
BASE64Encoder base64in16 = new BASE64Encoder();
String result2 = base64in16.encode(str16.getBytes());
// 打印结果
System.out.println("【结果1】 base64二进制字节流:");
System.out.println(result);
System.out.println("【结果2】 SHA-256 十六进制: ");
System.out.println(str16);
System.out.println("【结果2:】 BASE64 十六进制:");
System.out.println(result2);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
2.2.1 代码分析
首先,使用 MessageDigest.getInstance("SHA-256")
获取 SHA-256 的消息摘要对象。
将字符串 “helloworld” 编码为字节数组,并使用 SHA-256 消息摘要对象计算其哈希值。这一部分在以下行完成:
代码语言:javascript复制byte[] hash = sha256.digest(content.getBytes(StandardCharsets.UTF_8));
将 SHA-256 哈希值转换为十六进制字符串。该步骤对应‘【结果2】 SHA-256 十六进制’的输出结果,这一部分在以下代码中完成:
代码语言:javascript复制StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
String str16 = hexString.toString();
将二进制形式的 SHA-256 哈希值转换为 BASE64 编码的字符串,该步骤对应‘【结果1】’的输出结果。这一部分在以下代码中完成:
代码语言:javascript复制BASE64Encoder base64 = new BASE64Encoder();
String result = base64.encode(hash);
将十六进制形式的 SHA-256 哈希值转换为 BASE64 编码的字符串,该步骤对应‘【结果2:】 BASE64 十六进制’的输出结果。这一部分在以下代码中完成:
代码语言:javascript复制BASE64Encoder base64in16 = new BASE64Encoder();
String result2 = base64in16.encode(str16.getBytes());
打印结果:
代码语言:javascript复制System.out.println("【结果1】 base64二进制字节流:");
System.out.println(result);
System.out.println("【结果2】 SHA-256 十六进制: ");
System.out.println(str16);
System.out.println("【结果2:】 BASE64 十六进制:");
System.out.println(result2);
2.2.2 输出结果
代码语言:javascript复制【结果1】 base64二进制字节流:
k2oYXKqiZrucvpgengXLeM1zKwsygOuURBK7b4 PB68=
【结果2】 SHA-256 十六进制:
936a185caaa266bb9cbe981e9e05cb78cd732b0b3280eb944412bb6f8f8f07af
【结果2:】 BASE64 十六进制:
OTM2YTE4NWNhYWEyNjZiYjljYmU5ODFlOWUwNWNiNzhjZDczMmIwYjMyODBlYjk0NDQxMmJiNmY4
ZjhmMDdhZg==
3 实验总结
Java 示例中的【结果1】使用的是标准的 Java 加密库中的 MessageDigest 类来计算 SHA-256 哈希值,然后使用 BASE64Encoder 类将二进制哈希值转换为 BASE64 编码的字符串。
【结果2】的BASE64计算输出则与使用PowerShell计算相同 ,因为在PowerShell中使用的是 Get-FileHash
命令来计算文件的 SHA-256 哈希值,该输出对应java【结果2】中十六进制SHA-256的计算。在PowerShell中Step4计算的BASE64编码是十六进制的SHA-256值。
在实际操作中要注意的就是加密的字符串是否为相同的进制位。