有一段基于java的加解密代码,由于对方不愿意翻译成.net,自己又对java不熟悉,所以困苦了。
求助:翻译!
java源代码:
import java.nio.charset.Charset; import java.security.Key; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; import org.dommons.core.string.Stringure; import com.bstek.common.lang.StringUtils; import com.bstek.common.log.Logger; import com.bstek.common.log.LoggerFactory; /** * 传输报文加解密<br/> * (1)首先对securetKey做一次SHA-256散列,得到一个256位的key <br/> * (2)用该key对要传输的数据做AES加密 <br/> * ClassName:Util <br/> */ public class Util { private static final Logger log = LoggerFactory.getInstance().getLogger(Util.class); private static String SHA_256 = "SHA-256"; // 算法名称 private static String AES = "AES"; // 算法名称 private static String CHARSET = "UTF-8"; // 编码 private static String aop_signature = "_signature"; private static String timestamp = "_timestamp"; /** * 过滤 * @param params 参数 * @param secret 签名 * @return 是否合法 */ public static Map<String, String> filter(Map<String, String> params, String secret) { String _sign = params.remove(aop_signature); if (_sign != null && !_sign.equals(signature(Stringure.empty, params, secret))) { throw new IllegalArgumentException("sign failed"); } Map<String, String> retValue = new HashMap<String, String>(params); Map<String, String> sysMap = new HashMap<String, String>(); sysMap.put(timestamp, retValue.remove(timestamp)); decode(secret, retValue); retValue.putAll(sysMap); return retValue; } /** * 解密 * @param token 授权码 * @param params 入参 */ private static void decode(String token, Map<String, String> params) { for (String key : params.keySet()) { if (Stringure.isEmpty(params.get(key))) { continue; } params.put(key, decode(params.get(key),token)); } } /** * 使用key对value进行加密 * @param value * @param secretkey * @return */ public static String encode(String value, String secretkey) { try { // 对key进行SHA-256加密 String key = encodeBySHA256(secretkey.getBytes(CHARSET)); // 使用得到的key对value进行AES加密 Cipher cipher = Cipher.getInstance(AES); byte[] bytes = hex2bytes(key); cipher.init(Cipher.ENCRYPT_MODE, generateKey(bytes)); byte[] byteFina = cipher.doFinal(value.getBytes(CHARSET)); return bytes2Hex(byteFina); } catch (Exception e) { log.error("加密失败:" + e.getMessage(), e); } return null; } /** * 使用key对value进行解密 * @param value * @param secretkey * @return */ public static String decode(String value, String secretkey) { try { // 对key进行SHA-256加密 String key = encodeBySHA256(secretkey.getBytes(CHARSET)); // 使用得到的key对value进行AES解密 value = new String(value.getBytes(CHARSET)); byte[] byteValue = hex2bytes(value); byte[] byteKey = hex2bytes(key); Cipher cipher = Cipher.getInstance(AES); cipher.init(Cipher.DECRYPT_MODE, generateKey(byteKey)); byte[] byteFina = cipher.doFinal(byteValue); return new String(byteFina, CHARSET); } catch (Exception e) { log.error("解密失败:" + e.getMessage(), e); } return null; } /** * 根据SHA加密过的密钥生成密钥对象 * @param seed * @return */ private static Key generateKey(byte[] seed) { try { KeyGenerator keyGenerator = KeyGenerator.getInstance(AES); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(seed); keyGenerator.init(128, secureRandom); Key key = keyGenerator.generateKey(); return key; } catch (Exception e) { log.error("key生成失败:" + e.getMessage(), e); } return null; } /** * SHA-256加密 * @Description: * @param value * @return * @throws NoSuchAlgorithmException */ private static String encodeBySHA256(byte[] bytes) throws NoSuchAlgorithmException { MessageDigest messageDigest = null; try { messageDigest = MessageDigest.getInstance(SHA_256); messageDigest.reset(); messageDigest.update(bytes); byte[] byteArray = messageDigest.digest(); return bytes2Hex(byteArray); } catch (NoSuchAlgorithmException e) { log.error("SHA256加密失败:" + e.getMessage(), e); throw e; } } /** * 二进制转换为十六进制 * @param bts * @return */ private static String bytes2Hex(byte[] bts) { String des = ""; String tmp = null; for (int i = 0; i < bts.length; i++) { tmp = (Integer.toHexString(bts[i] & 0xFF)); if (tmp.length() == 1) { des += 0; } des += tmp; } return des; } /** * 十六进制转换为二进制 * @Description: * @param hex * @return */ private static byte[] hex2bytes(String hex) { if (hex == null || hex.isEmpty()) return null; hex = hex.toUpperCase(); int length = hex.length() / 2; char[] hexChars = hex.toCharArray(); byte[] bytes = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; bytes[i] = (byte) (char2Byte(hexChars[pos]) << 4 | char2Byte(hexChars[pos + 1])); } return bytes; } private static byte char2Byte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } /** * 生成签名 * @param url 请求地址 * @param params 参数集 * @param secret 密钥 * @return 签名 */ public static String signature(String url, Map<String, String> params, String secret) { List<String> list = new ArrayList(); for (Entry<String, String> en : params.entrySet()) { list.add(trim(en.getKey()) + trim(en.getValue())); } Collections.sort(list); if (trim(url).length() > 0) list.add(0, url); return Hex.encodeHexString(hmac(secret, list.toArray(new String[list.size()]))); } /** * 修剪字符串 * @param content 字符串 * @return 修剪后字符串 */ public static String trim(Object content) { CharSequence cs = content == null ? null : (content instanceof CharSequence) ? (CharSequence) content : String.valueOf(content); if (cs == null) return StringUtils.EMPTY_STRING; int start = 0; int end = cs.length() - 1; while (start <= end && Character.isWhitespace(cs.charAt(start))) start++; while (end >= start && Character.isWhitespace(cs.charAt(end))) end--; return cs.subSequence(start, end + 1).toString(); } /** * HMAC 转换 * @param secret 密钥 * @param datas 数据集 * @return 字节 */ static byte[] hmac(String secret, String... datas) { SecretKeySpec key = new SecretKeySpec(bytes(secret), "HmacSHA1"); Mac mac = null; try { mac = Mac.getInstance("HmacSHA1"); mac.init(key); } catch (Exception e) { throw new UnsupportedOperationException(e); } for (String data : datas) { mac.update(bytes(data)); } return mac.doFinal(); } /** * 转换字节 * @param content 文本内容 * @return 字节 */ static byte[] bytes(String content) { if (content == null) return new byte[0]; return content.getBytes(Charset.forName("UTF-8")); } }
以下是我翻译了一半的代码,其中几段不知道怎么做了。
using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; public static class HupunSecurity { private static string SHA_256 = "SHA-256"; // 算法名称 private static string AES = "AES"; // 算法名称 private const string CHARSET = "UTF-8"; // 编码 private static string aop_signature = "_signature"; private static string timestamp = "_timestamp"; private static TValue GetAndRemove<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key) { if (dict.TryGetValue(key, out var value)) { dict.Remove(key); } return value; } private static byte[] GetBytes(this string source, string charset = CHARSET) { if (string.IsNullOrEmpty(source)) { return new byte[0]; } return Encoding.GetEncoding(charset) .GetBytes(source); } private static string GetString(this byte[] source, string charset = CHARSET) { if (source == null || source.Length == 0) { return ""; } return Encoding.GetEncoding(charset) .GetString(source); } private static string ToHex(this byte[] source, bool upcase = true) { if (source == null || source.Length == 0) { return ""; } var result = BitConverter.ToString(source) .Replace("-", ""); if (upcase) { result = result.ToUpper(); } else { result = result.ToLower(); } return result; } private static byte[] FromHex(this string source) { if (string.IsNullOrEmpty(source)) { return new byte[0]; } source = source.Replace("-", "") .Replace(" ", "") .ToUpper(); if (source.Length % 2 != 0) { throw new ArgumentOutOfRangeException(nameof(source), "长度必须是偶数"); } byte[] result = new byte[source.Length]; for (int i = 0; i < result.Length; i++) { var high = (byte)"0123456789ABCDEF".IndexOf(source[i * 2]); var low = (byte)"0123456789ABCDEF".IndexOf(source[i * 2 + 1]); if (high < 0 || low < 0) { throw new ArgumentOutOfRangeException(nameof(source), "不是合法的16进制字符串"); } result[i] = (byte)((high << 4) & low); } return result; } /** * 过滤 * @param params 参数 * @param secret 签名 * @return 是否合法 */ public static IDictionary<string, string> Filter(IDictionary<string, string> @params, string secret) { string sign = @params.GetAndRemove(aop_signature); if (sign != null && !sign.Equals(Signature(string.Empty, @params, secret))) { throw new ArgumentException("sign failed"); } Dictionary<string, string> retValue = new Dictionary<string, string>(@params); Dictionary<string, string> sysMap = new Dictionary<string, string> { { timestamp, retValue.GetAndRemove(timestamp) } }; Decode(secret, retValue); foreach (var key in sysMap.Keys) { retValue[key] = sysMap[key]; } return retValue; } /** * 解密 * @param token 授权码 * @param params 入参 */ private static void Decode(string token, IDictionary<string, string> @params) { foreach (string key in @params.Keys) { var value = @params[key]; if (!string.IsNullOrEmpty(value)) { @params[key] = Decode(value, token); } } } /** * 使用key对value进行加密 * @param value * @param secretkey * @return */ public static string Encode(string value, string secretkey) { // 对key进行SHA-256加密 string key = EncodeBySHA256(secretkey.GetBytes(CHARSET)); // 使用得到的key对value进行AES加密 var aes = new AesCryptoServiceProvider(); aes.GenerateKey(); aes.KeySize = 128; Cipher cipher = Cipher.getInstance(AES); byte[] bytes = key.FromHex(); cipher.init(Cipher.ENCRYPT_MODE, GenerateKey(bytes)); byte[] byteFina = cipher.doFinal(value.GetBytes(CHARSET)); return byteFina.ToHex(); } /** * 使用key对value进行解密 * @param value * @param secretkey * @return */ public static string Decode(string value, string secretkey) { // 对key进行SHA-256加密 string key = EncodeBySHA256(secretkey.GetBytes(CHARSET)); // 使用得到的key对value进行AES解密 value = value ?? ""; byte[] byteValue = value.FromHex(); byte[] byteKey = key.FromHex(); byte[] result = null; { // //下面代码怎么翻译? // Cipher cipher = Cipher.getInstance(AES); cipher.init(Cipher.DECRYPT_MODE, GenerateKey(byteKey)); result = cipher.doFinal(byteValue); } return result.GetString(); } /** * 根据SHA加密过的密钥生成密钥对象 * @param seed * @return */ private static Key GenerateKey(byte[] seed) { // // 这段代码怎么翻译? // KeyGenerator keyGenerator = KeyGenerator.getInstance(AES); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(seed); keyGenerator.init(128, secureRandom); Key key = keyGenerator.generateKey(); return key; } /** * SHA-256加密 * @Description: * @param value * @return * @throws NoSuchAlgorithmException */ private static string EncodeBySHA256(byte[] bytes) { var sha256 = SHA256.Create(); sha256.ComputeHash(bytes); return sha256.Hash.ToHex(); } /** * 生成签名 * @param url 请求地址 * @param params 参数集 * @param secret 密钥 * @return 签名 */ public static string Signature(string url, IDictionary<string, string> @params, string secret) { List<string> list = new List<string>(); foreach (var entry in @params) { list.Add(entry.Key.Trim() + entry.Value.Trim()); } list.Sort(); if (url.Trim().Length > 0) { list.Insert(0, url); } return Hmac(secret, list.ToArray()).ToHex(); } /** * HMAC 转换 * @param secret 密钥 * @param datas 数据集 * @return 字节 */ static byte[] Hmac(string secret, params string[] datas) { // // 这段代码怎么翻译? // SecretKeySpec key = new SecretKeySpec(secret.GetBytes(), "HmacSHA1"); Mac mac = null; mac = Mac.getInstance("HmacSHA1"); mac.init(key); foreach (string data in datas) { mac.update(data.GetBytes()); } return mac.doFinal(); } }
vs 有一个版本是支持java的,装上,然后编译成dll, 用.net reflector反编译成 c#,大功靠成。
VS2005仍保留Visual J#,VS2010 没了, J#语法就是java语法
直接看.net的AES加密.
你看我封装的加密 Helper,自己认为还是不错的(相对于网上其他人的加密),我简单看了下,应该都包含了你想要的代码:
https://github.com/liqingwen2015/Wen.Helpers/blob/master/Wen.Helpers.Common/Security/SecurityHelper.cs
或者这里:
http://www.cnblogs.com/liqingwen/p/6155694.html
网上找个JAVA加密的代码
这个我弄过,联系我吧