1.Java计算加密代码如下:
public classMyClass {
public static voidmain(String[] args){
String str ="APP&1122322134534&AbcdeffFDDGHJDS";
String finalStr = HmacSha1.genHMAC(str,"123456");
System.out.println("finalStr:"+finalStr);// 0PGsANnMw+1yep5TlAXBLO2Ko3c=
}
}
packagestudy.telchina.com.javatestlib;
importorg.apache.commons.codec.binary.Base64;
importjava.security.InvalidKeyException;
importjava.security.NoSuchAlgorithmException;
importjavax.crypto.Mac;
importjavax.crypto.spec.SecretKeySpec;
public classHmacSha1 {
private static finalStringHMAC_SHA1_ALGORITHM="HmacSHA1";
/**
* 使用 HMAC-SHA1 签名方法对data进行签名
*
*@paramdata被签名的字符串
*@paramkey密钥
*@return加密后的字符串
*/
public staticString genHMAC(String data, String key) {
byte[] result =null;
try{
//根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
SecretKeySpec signinKey =newSecretKeySpec(key.getBytes(),HMAC_SHA1_ALGORITHM);
//生成一个指定 Mac 算法 的 Mac 对象
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
//用给定密钥初始化 Mac 对象
mac.init(signinKey);
//完成 Mac 操作
byte[] rawHmac = mac.doFinal(data.getBytes());
result = Base64.encodeBase64(rawHmac);
}catch(NoSuchAlgorithmException e) {
System.err.println(e.getMessage());
}catch(InvalidKeyException e) {
System.err.println(e.getMessage());
}
if(null!= result) {
return newString(result);
}else{
return null;
}
}
}
项目引入jar包:commons-codec-1.14.jar,最终得到的计算结果是:0PGsANnMw+1yep5TlAXBLO2Ko3c=
2.ionic中计算方式如下:
首先引入插件,执行命令如下:
npm install crypto-js
然后在页面引入
import hmacSHA1 from 'crypto-js/hmac-sha1';
import Base64 from 'crypto-js/enc-base64';
在参考他的这种方式在页面中写下,看下源文件中有hmacSHA1,由于java端是采用的这个算法,所以移动端必须采用这个算法,将hmacSHA2565改为hmacSHA1

移动端页面计算加密代码整理如下:
var str = "APP&1122322134534&AbcdeffFDDGHJDS";
console.log("加密前:"+str);
var a = Base64.stringify(hmacSHA1(str, "123456"));
console.log("加密后:"+a);
str就是我们我加密的内容,123456 就是我们双方约定的密钥
移动端计算结果如下:

发现与java端计算的结果并不一致,我们在看下java代码

注意红框中的代码,发现是做了一步Base64运算,调用了encodeBase64方法,而移动端调用了Base64.stringify方法
我们再去看下Base64中的源码如下:

发现并没有卵用,参数都不符合,看来这个是用不了了,后来同事说统一编码用utf-8,想了想可能是这个原因,于是更改代码如下:
var str = "APP&1122322134534&AbcdeffFDDGHJDS";
console.log("加密前:"+str);
var a = hmacSHA1(str, "123456").toString(CryptoJS.enc.utf8);
console.log("加密后:"+a);
结果如下:

还是没有卵用,参考Java代码,想了想还是得和Base64挂上,于是我又稍微改了下:
var str = "APP&1122322134534&AbcdeffFDDGHJDS";
console.log("加密前:"+str);
var a = hmacSHA1(str, "123456").toString(CryptoJS.enc.Base64);
console.log("加密后:"+a);
于是奇迹出现了:

与Java计算结果完全一致,最后在优化了下移动端的引入结果如下:
import * as CryptoJS from 'crypto-js/crypto-js';
var str = "APP&1122322134534&AbcdeffFDDGHJDS";
console.log("加密前:"+str);
var a = CryptoJS.HmacSHA1(str, "123456").toString(CryptoJS.enc.Base64);
console.log("加密后:"+a);
针对字母特殊字符数字的组合加密已经测试正常,完全满足了项目的需求,稍微试了下针对中文的加密移动端与Java端并不完全一致,由于没这个需求就没在继续探究下去,当然保底方案是写到我们自己开发的cordova插件中去调用,目前里面已经封装了三个方法,也不差在多一个哈哈
网友评论