最近在带一个新人小易 , 由于经常犯错,现在把我的低血压都治好了。
不过,小易的心态一直很不错,他不觉得被我批评有什么丢人的,反而每次读完我的文章后觉得自己又可以了。
因此,我觉得小易大有前途,再这么干个一两年,老板要是觉得我的性价比低了,
没准就把我辞退留下小易了。一想到这,我竟然枯燥一笑了。
那天,我闲来无聊,小易跑过来找我,说能不能用C# 调用Java代码,实现接口加密。
Excuse me 告辞,
这孩子还真是初生牛犊不怕虎啊,
不过男人怎么能说不行呢,更何况是身为暖男的我。
一.环境配置
- javaVersion :”1.8.0_31”
- IKVM:ikvm-8.1.5717.0
IKVM下载地址:链接:https://pan.baidu.com/s/1h2Ye5_euPV1567gjMyHYTw 提取码:44to
IKVM官网地址:链接:http://www.ikvm.net/
IKVM 如果版本过低 ,无法适用 jdk高版本,如:IKVM7.1无法使用jdk1.8的。
IKVM需要配置环境 :将IKVM.NET的bin文件夹的地址添加到环境变量。
计算机右键属性–高级系统设置–高级–环境变量–在系统变量中找到PATH–将bin文件夹的地址添加进去。
IKVM.NET是Java for Mono和Microsoft .NET Framework的实现。它包括以下组件:
- 在.NET中实现的Java虚拟机
- Java类库的.NET实现
- 支持Java和.NET互操作性的工具
二.生成jar包和dll文件
2.1 实现SH256加密
//package com.example.think.controller.test; 删除包名称
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
/**
* @program: think
* @description:
* @author: SnailThink
* @create: 2020-11-12 14:14
**/
public class IkvmSh256EncryptionHelp {
public String getTestStr(){
return "AAA";
}
/**
* 加密
* @return
*/
public String passwardSh256Encryption() {
final String secret = "tBKY94PUFZ3a";
Map<String, String> params = new HashMap<String, String>();
params.put("api_key", "dtt-13457");
params.put("nonce_str", "123");
params.put("timestamp", "2020-04-28 09:50:06");
params.put("body", "{\n" +
" \"token\": \"TVSSsendtasknoservice\",\n" +
" \"taskNo\": \"12345\",\n" +
" \"receiveNo\": \"12345\",\n" +
" \"riskLevel\": \"H\"\n" +
"}");
List<String> paramList = new ArrayList<>();
for (Map.Entry<String, String> entry : params.entrySet()) {
paramList.add(entry.getKey() + "=" + entry.getValue());
}
Collections.sort(paramList);
StringBuilder sb = new StringBuilder();
sb.append(secret);
for (String paramStr : paramList) {
sb.append(paramStr);
sb.append("&");
}
sb.replace(sb.length() - 1, sb.length(), secret);
System.out.println(sb.toString());
String aa = getSHA256(sb.toString());
System.out.println(aa);
return aa;
}
/**
* 利用java原生的类实现SHA256加密
*
* @param str
* @return
*/
public static String getSHA256(String str) {
MessageDigest messageDigest;
String encodestr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes("UTF-8"));
encodestr = byte2Hex(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encodestr;
}
//15 转16进制
/**
* 将byte转为16进制
*
* @param bytes
* @return
*/
public static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
String temp = null;
for (int i = 0; i < bytes.length; i++) {
temp = Integer.toHexString(bytes[i] & 0xFF);
if (temp.length() == 1) {
//1得到一位的进行补0操作
stringBuffer.append("0");
}
stringBuffer.append(temp);
}
return stringBuffer.toString();
}
}
2.2 生成jar包
1.将java文件转换为class文件
javac IkvmSh256EncryptionHelp.java
如何出现以下错误:是由于没有使用utf-8转码的则使用
javac -encoding UTF-8 IkvmSh256EncryptionHelp.java
执行成功后如下图所示
将class文件转换为jar包
jar cvf IkvmSh256EncryptionHelp.jar IkvmSh256EncryptionHelp.class
下面就到关键的一步了将jar包转换为dll文件
//这里是把IkvmSh256EncryptionHelp.jar包转成dll
ikvmc -target:library IkvmSh256EncryptionHelp.jar
dll文件生成成功
三 项目调用
3.1 创建一个winform项目测试并安装Nuget
3.2 在项目中添加 IkvmSh256EncryptionHelp.dll
3.3 调用sh256加密
#region NET 调用java 代码
/// <summary>
/// NET 调用java 代码
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button26_Click(object sender, EventArgs e)
{
IkvmSh256EncryptionHelp ikvmHelp = new IkvmSh256EncryptionHelp();
string testStr = ikvmHelp.getTestStr();
string passwardSh256Encryption = ikvmHelp.passwardSh256Encryption();
}
#endregion
四 反编译dll文件
其实比较好奇内部是如何实现的,那么我们可以先看看dll文件反编译后的内容,可能有同学就要问了,用什么反
编译软件啊,我没有啊,傻瓜 身为暖男的我怎么不会为你们考虑呢,链接放在下面了
链接:https://pan.baidu.com/s/108VDeLkfarDFTlksSl5Brw
提取码:gv56
根据反编译的文件可以看到
public virtual string getTestStr() {
return "AAA"
}
[MethodImpl(MethodImplOptions.NoInlining)]
public virtual string passwardSh256Encryption()
{
HashMap hashMap = new HashMap();
hashMap.put("api_key", "dtt-13457");
hashMap.put("nonce_str", "123");
hashMap.put("timestamp", "2020-04-28 09:50:06");
hashMap.put("body", "{\n \"token\": \"TVSSsendtasknoservice\",\n \"taskNo\": \"12345\",\n \"receiveNo\": \"12345\",\n \"riskLevel\": \"H\"\n}");
ArrayList arrayList = new ArrayList();
Iterator iterator = hashMap.entrySet().iterator();
while (iterator.hasNext())
{
Map.Entry entry = (Map.Entry)iterator.next();
arrayList.add(new StringBuilder().append((string)entry.getKey()).append("=").append((string)entry.getValue()).toString());
}
Collections.sort(arrayList);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("tBKY94PUFZ3a");
Iterator iterator2 = arrayList.iterator();
while (iterator2.hasNext())
{
string text = (string)iterator2.next();
stringBuilder.append(text);
stringBuilder.append("&");
}
stringBuilder.replace(stringBuilder.length() - 1, stringBuilder.length(), "tBKY94PUFZ3a");
System.get_out().println(stringBuilder.toString());
string sHA = IkvmSh256EncryptionHelp.getSHA256(stringBuilder.toString());
System.get_out().println(sHA);
return sHA;
}
五 回顾
这个使用SH256加密主要是一个思路,在工作中遇到对接Java接口,涉及Java加密或者签名问题.net无法实现
就将java代码编辑为dll文件给net调用。