前言
工业领域上位机软件与管理系统通常使用不同编程语言实现,比如我们的上位机软件通常使用C#,而MES、WMS则使用Java Web开发,而基础数据又在各系统之间进行传递和同步,比如用户信息。在Java Web开发中经常会使用框架简化开发,比如安全认证(包括登录身份验证与授权)会使用比较流行的框架Shiro,Shiro本身内置了SimpleHash(可以指定加密算法、盐值、哈希次数)简化对密码等敏感信息的加密存储。这是在上位机系统中如果同步了管理系统的用户数据,却不能识别同步过来的密码是行不通的,这样就需要在C#中有一致的加密算法支持,才能用同步过来的用户进行身份验证。下面就把核心代码分享一下,供大家参阅。
核心代码
Java代码
package com.wongoing.sys.shiro;
import java.security.Key;
import org.apache.shiro.codec.Hex;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.crypto.hash.SimpleHash;
/**
* 功能说明:Shiro框架辅助类
* 修改说明:
* @author zhenglibing
* @date 2017年10月27日 上午10:59:58
* @version 0.1
*/
public class ShiroHelper {
/**
* 默认的盐值2
*/
public static final String SALT2 = "WONGOING";
/**
* 默认加密次数
*/
public static final int HASHITERATIONS = 1024;
/**
* MD5加密算法
*/
public static final String ALGORITHM_MD5 = "MD5";
/**
* SHA-1加密算法
*/
public static final String ALGORITHM_SHA1 = "SHA-1";
/**
* SHA-256加密算法
*/
public static final String ALGORITHM_SHA1256 = "SHA-256";
/**
* SHA-512加密算法
*/
public static final String ALGORITHM_SHA512 = "SHA-512";
/**
* 功能说明:加密算法实现
* 修改说明:
* @author zhenglibing
* @date 2017年10月27日 上午11:03:19
* @param source 要加密的原文,通常传入密码明文
* @param algorithmName 要使用的加密算法,如MD5、SHA-1、SHA-256、SHA-512
* @param salt1 盐值1
* @param salt2 盐值2
* @param hashIterations 要加密的次数
* @return 返回加密后的密文
*/
public static String encrypt(String source, String algorithmName, String salt1, String salt2, int hashIterations) {
if (null == source) source = "";
if (null == algorithmName) algorithmName = "MD5";
if (null == salt1) salt1 = "";
if (null == salt2) salt2 = "";
SimpleHash hash = new SimpleHash(algorithmName, source, salt1 + salt2, hashIterations);
String encode = hash.toHex();
return encode;
}
/**
* 功能说明:MD5加密实现
* 修改说明:
* @author zhenglibing
* @date 2017年10月27日 上午11:07:08
* @param source 要加密的原文,通常传入密码明文
* @param salt1 盐值1
* @param salt2 盐值2
* @param hashIterations 要加密的次数
* @return 返回加密后的密文
*/
public static String md5Encrypt(String source, String salt1, String salt2, int hashIterations) {
if (null == source) source = "";
if (null == salt1) salt1 = "";
if (null == salt2) salt2 = "";
SimpleHash hash = new SimpleHash("MD5", source, salt1 + salt2, hashIterations);
String encode = hash.toHex();
return encode;
}
/**
* 功能说明:SHA1加密实现
* 修改说明:
* @author zhenglibing
* @date 2017年10月27日 上午11:08:51
* @param source 要加密的原文,通常输入密码明文
* @param salt1 盐值1
* @param salt2 盐值2
* @param hashIterations 要加密的次数
* @return 返回加密后的密文
*/
public static String sha1Encrypt(String source, String salt1, String salt2, int hashIterations) {
if (null == source) source = "";
if (null == salt1) salt1 = "";
if (null == salt2) salt2 = "";
SimpleHash hash = new SimpleHash("SHA-1", source, salt1 + salt2, hashIterations);
String encode = hash.toHex();
return encode;
}
}
C#代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
namespace Mesnac.Basic
{
/// <summary>
/// 加密辅助类
/// </summary>
public class EncryptHelper
{
#region 常量定义
/// <summary>
/// 默认的盐值2
/// </summary>
public static readonly string SALT2 = "WONGOING";
/// <summary>
/// 默认加密次数
/// </summary>
public static readonly int HASHITERATIONS = 1024;
/// <summary>
/// MD5加密算法
/// </summary>
public static readonly string ALGORITHM_MD5 = "MD5";
/// <summary>
/// SHA-1加密算法
/// </summary>
public static readonly string ALGORITHM_SHA1 = "SHA-1";
/// <summary>
/// SHA-256加密算法
/// </summary>
public static readonly string ALGORITHM_SHA256 = "SHA-256";
/// <summary>
/// SHA-512加密算法
/// </summary>
public static readonly string ALGORITHM_SHA512 = "SHA-512";
#endregion
#region 方法定义
/// <summary>
/// 加密方法
/// </summary>
/// <param name="source">要加密的原文, 通常传入密码明文</param>
/// <param name="algorithmName">要使用的加密算法,如MD5、SHA-1、SHA-256、SHA-512</param>
/// <param name="salt1">盐值1</param>
/// <param name="salt2">盐值2</param>
/// <param name="hashIterations">要加密的次数</param>
/// <returns>返回加密后的密文</returns>
public static String Encrypt(string source, string algorithmName, string salt1, string salt2, int hashIterations)
{
if (null == source) source = "";
if (null == algorithmName) algorithmName = "MD5";
if (null == salt1) salt1 = "";
if (null == salt2) salt2 = "";
string result = String.Empty;
if (algorithmName == ALGORITHM_MD5)
{
result = MD5Encrypt(source, salt1, salt2, hashIterations);
}
else if (algorithmName == ALGORITHM_SHA1)
{
result = SHA1Encrypt(source, salt1, salt2, hashIterations);
}
else if (algorithmName == ALGORITHM_SHA256)
{
result = SHA256Encrypt(source, salt1, salt2, hashIterations);
}
else if (algorithmName == ALGORITHM_SHA512)
{
result = SHA512Encrypt(source, salt1, salt2, hashIterations);
}
return result;
}
/// <summary>
/// MD5加密方法
/// </summary>
/// <param name="source">要加密的原文, 通常传入密码明文</param>
/// <param name="salt1">盐值1</param>
/// <param name="salt2">盐值2</param>
/// <param name="hashIterations">要加密的次数</param>
/// <returns>返回加密后的密文</returns>
public static string MD5Encrypt(string source, string salt1, string salt2, int hashIterations)
{
byte[] saltPasswordValue = UTF8Encoding.UTF8.GetBytes(salt1 + salt2 + source);
MD5 md5 = new MD5CryptoServiceProvider();
saltPasswordValue = md5.ComputeHash(saltPasswordValue);
for (int i = 0; i < hashIterations - 1; i++)
{
saltPasswordValue = md5.ComputeHash(saltPasswordValue);
}
md5.Dispose();
string result = BitConverter.ToString(saltPasswordValue);
result = result.Replace("-", String.Empty).ToLower();
return result;
}
/// <summary>
/// SHA1加密方法
/// </summary>
/// <param name="source">要加密的原文, 通常传入密码明文</param>
/// <param name="salt1">盐值1</param>
/// <param name="salt2">盐值2</param>
/// <param name="hashIterations">要加密的次数</param>
/// <returns>返回加密后的密文</returns>
public static string SHA1Encrypt(string source, string salt1, string salt2, int hashIterations)
{
byte[] saltPasswordValue = UTF8Encoding.UTF8.GetBytes(salt1 + salt2 + source);
SHA1 sha1 = new SHA1CryptoServiceProvider();
saltPasswordValue = sha1.ComputeHash(saltPasswordValue);
for (int i = 0; i < hashIterations - 1; i++)
{
saltPasswordValue = sha1.ComputeHash(saltPasswordValue);
}
sha1.Dispose();
string result = BitConverter.ToString(saltPasswordValue);
result = result.Replace("-", String.Empty).ToLower();
return result;
}
/// <summary>
/// SHA256加密方法
/// </summary>
/// <param name="source">要加密的原文, 通常传入密码明文</param>
/// <param name="salt1">盐值1</param>
/// <param name="salt2">盐值2</param>
/// <param name="hashIterations">要加密的次数</param>
/// <returns>返回加密后的密文</returns>
public static string SHA256Encrypt(string source, string salt1, string salt2, int hashIterations)
{
byte[] saltPasswordValue = UTF8Encoding.UTF8.GetBytes(salt1 + salt2 + source);
SHA256 sha256 = new SHA256CryptoServiceProvider();
saltPasswordValue = sha256.ComputeHash(saltPasswordValue);
for (int i = 0; i < hashIterations - 1; i++)
{
saltPasswordValue = sha256.ComputeHash(saltPasswordValue);
}
sha256.Dispose();
string result = BitConverter.ToString(saltPasswordValue);
result = result.Replace("-", String.Empty).ToLower();
return result;
}
/// <summary>
/// SHA512加密方法
/// </summary>
/// <param name="source">要加密的原文, 通常传入密码明文</param>
/// <param name="salt1">盐值1</param>
/// <param name="salt2">盐值2</param>
/// <param name="hashIterations">要加密的次数</param>
/// <returns>返回加密后的密文</returns>
public static string SHA512Encrypt(string source, string salt1, string salt2, int hashIterations)
{
byte[] saltPasswordValue = UTF8Encoding.UTF8.GetBytes(salt1 + salt2 + source);
SHA512 sha512 = new SHA512CryptoServiceProvider();
saltPasswordValue = sha512.ComputeHash(saltPasswordValue);
for (int i = 0; i < hashIterations - 1; i++)
{
saltPasswordValue = sha512.ComputeHash(saltPasswordValue);
}
sha512.Dispose();
string result = BitConverter.ToString(saltPasswordValue);
result = result.Replace("-", String.Empty).ToLower();
return result;
}
#endregion
}
}
注意
1、编码处理要一致
java代码和C#代码在把byte数组处理为加密字符串时要使用一致的方式,
比如java
String encode = hash.toHex();
则C#
string result = BitConverter.ToString(saltPasswordValue);
如果java
String encode = hash.toBase64();
则C#
string result = Convert.ToBase64String(saltPasswordValue);
2、加密后的字符串大小写要一致,本方法都处理为小写了。