JAVA BASE64 HMACSHA512加密

需求是 会员从C#迁移到了JAVA,但是旧的密码是BASE64(HMACSHA512(value))加密的,用户体验不变,所以java端也要实现这个,可我生成的这么都不对。
c#: PBKDF2
C#生成的 类似:zYKcuNTKMZzvmCptYkXbbfCXkwUiQKf/6qZi/XRNNxSf08pMRcrBO34cj9DMyoQCFOLnbQgDz9aalz8yjbQwng==
而我生成的:
YjA4OTc2ZDJkNmNhYTk4OGJmODI0M2M1OWExZTJjYjMwMmMzNzFmYzA0ZTA2ZTE0ZjkyNGQyNWNiNGI2MTA1ZDc1YTUzNTJjZjI1YjY4ODlhY2JhMTk2M2MwNzcyODE4MjQzZmY3YzczZjMzY2I2OWEyMGIyM2ZkYmNiOTAwOGY=
哪有问题?

下面是代码

import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
import java.util.Base64;


public class HMAC {

    /**
     * 定义加密方式
     * MAC算法可选以下多种算法
     * <pre>
     * HmacMD5
     * HmacSHA1
     * HmacSHA256
     * HmacSHA384
     * HmacSHA512
     * </pre>
     */
    private static final String HMAC_SHA1 = "HmacSHA512";

    /**
     * 生成签名数据_HmacSHA1加密
     *
     * @param data
     *            待加密的数据
     * @param key
     *            加密使用的key
     */
    public static String getSignature(String data, String key) throws Exception {

        byte[] keyBytes = key.getBytes();
        // 根据给定的字节数组构造一个密钥。
        SecretKeySpec signingKey = new SecretKeySpec(keyBytes, HMAC_SHA1);
        Mac mac = Mac.getInstance(HMAC_SHA1);
        mac.init(signingKey);

        byte[] rawHmac = mac.doFinal(data.getBytes());

        String hexBytes = byte2hex(rawHmac);
        return hexBytes;
    }

    private static String byte2hex(final byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            // 以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式。
            stmp = (java.lang.Integer.toHexString(b[n] & 0xFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            String signature = getSignature("3e043a92a204412cb7098b67c017b1cf", "ants@xpress");
            String base64String = Base64.getEncoder().encodeToString(signature.getBytes("UTF-8"));
            System.out.println(base64String);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

阅读 4.6k
2 个回答

直接对签名算法生成的字节数组做base64编码,不要先转成HAX string。

base64和转成hex都是将字节序列转成可以阅读的字符形式,一般在设计上不会同时使用,同时使用的话只会徒增结果长度,对安全性提升意义不大。

hmac是签名算法,作为开发者建议分清编码、摘要/哈希/杂凑、签名以及加密的区别

   public static byte[] getSignature(String data, String key) throws Exception {

        byte[] keyBytes = key.getBytes();
        // 根据给定的字节数组构造一个密钥。
        SecretKeySpec signingKey = new SecretKeySpec(keyBytes, HMAC_SHA1);
        Mac mac = Mac.getInstance(HMAC_SHA1);
        mac.init(signingKey);

        return mac.doFinal(data.getBytes());
    }
    
    public static void main(String[] args) {
        try {
            final byte[] signature1 = getSignature("3e043a92a204412cb7098b67c017b1cf", "ants@xpress");
            String base64String = Base64.getEncoder().encodeToString(signature1);
            System.out.println(base64String);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

你确定是 BASE64(HMACSHA512(value)) 还是 PBKDF2-HMACSHA512,这是两种完全不同的加密方式。后者的话你还需要dkLen、c和salt才能得到相同的结果。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏