同系列文章:
功能描述:
- 国家商用密码(一)SM2椭圆曲线公钥密码算法
- 国家商用密码(二)C#:基于BouncyCastle实现SM3密码杂凑算法
- 国家商用密码(三)C#:从HashAlgorithm类派生实现SM3密码杂凑算法
- 国家商用密码(四)开放动态库及演示程序
- 国家商用密码(五)基于SM2的软件授权码生成及校验
- 国家商用密码(六)椭圆曲线加密算法密钥生成器
- 国家商用密码(七)在Apache MINA上实现二进制流的SM4编解码器
- 国家商用密码(八)在Apache MINA上实现文本流的SM4编解码器
- 国家商用密码(九)在Apache MINA上实现二进制流数据报文的SM4编解码器
- 国家商用密码(十)在Apache MINA上实现文本流数据报文的SM4编解码器
源代码出售:
- 在Apache MINA上实现二进制流的SM4编解码器
- 在Apache MINA上实现文本流的SM4编解码器
- 在Apache MINA上实现二进制流数据报文的SM4编解码器
- 在Apache MINA上实现文本流数据报文的SM4编解码器
- 各个IoSession可独立设置通信密钥
jar包及测试程序下载:
价格:壹仟元人民币
微信:splashcn
SM4CodecFactory 2015-11-05.zip
源代码:
SM4TextCodecFactory.java
/* ----------------------------------------------------------
* 文件名称:SM4TextCodecFactory.java
*
* 作者:秦建辉
*
* QQ:36748897
*
* 博客:http://www.firstsolver.com/wordpress/
*
* 开发环境:
* NetBeans 8.0.2
* JDK 8u66
*
* 版本历史:
* V1.0 2015年11月05日
* 在Apache MINA上实现文本流的SM4编解码器
------------------------------------------------------------ */
package Com.FirstSolver.Security;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolEncoder;
public class SM4TextCodecFactory implements ProtocolCodecFactory {
// 编码器
private final SM4TextEncoderAdapter mEncoder;
// 解码器
private final SM4TextCumulativeDecoder mDecoder;
// 构造函数
public SM4TextCodecFactory() {
this(CipherMode.OFB, PaddingMode.PKCS7, StandardCharsets.UTF_8);
}
// 构造函数
public SM4TextCodecFactory(CipherMode mode) {
this(mode, PaddingMode.PKCS7, StandardCharsets.UTF_8);
}
// 构造函数
public SM4TextCodecFactory(CipherMode mode, PaddingMode padding) {
this(mode, padding, StandardCharsets.UTF_8);
}
/*
功能:构造函数
参数说明:
mode:运算模式,支持ECB、CBC、CFB、OFB(默认)、PCBC
padding:填充模式,支持PKCS7(默认)、ANSIX923、ISO10126、ISO7816、Zeros、None
charset:字符集编码,默认为UTF-8
*/
public SM4TextCodecFactory(CipherMode mode, PaddingMode padding, Charset charset) {
if (mode.getValue() > 4) throw new IllegalArgumentException("Unsupported cipher mode!");
mEncoder = new SM4TextEncoderAdapter(mode, padding, charset);
mDecoder = new SM4TextCumulativeDecoder(mode, padding, charset);
}
// 获取编码器
@Override
public ProtocolEncoder getEncoder(IoSession session) {
return mEncoder;
}
// 获取解码器
@Override
public ProtocolDecoder getDecoder(IoSession session) {
return mDecoder;
}
// 设置编码器加密密钥
public static void setEncoderKey(IoSession session, String value){
SM4TextEncoderAdapter.setSecretKey(session, value);
}
// 设置解码器解密密钥
public static void setDecoderKey(IoSession session, String value){
SM4TextCumulativeDecoder.setSecretKey(session, value);
}
// 获取编码器加密密钥
public static String getEncoderKey(IoSession session)
{
return (String)SM4TextEncoderAdapter.getSecretKey(session);
}
// 获取解码器解密密钥
public static String getDecoderKey(IoSession session)
{
return (String)SM4TextCumulativeDecoder.getSecretKey(session);
}
// 获取编码器字符集编码
public Charset getEncoderCharset() { return mEncoder.getCharset(); }
// 获取解码器字符集编码
public Charset getDecoderCharset() { return mDecoder.getCharset(); }
}
SM4TextEncoderAdapter.java
/* ----------------------------------------------------------
* 文件名称:SM4TextEncoderAdapter.java
*
* 作者:秦建辉
*
* QQ:36748897
*
* 博客:http://www.firstsolver.com/wordpress/
*
* 开发环境:
* NetBeans 8.0.2
* JDK 8u66
*
* 版本历史:
* V1.0 2015年11月05日
* 文本流的SM4编码器
------------------------------------------------------------ */
package Com.FirstSolver.Security;
import java.io.IOException;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
public class SM4TextEncoderAdapter implements ProtocolEncoder {
// 编码器属性键
private static final AttributeKey KEY_ENCRYPTOR = new AttributeKey(SM4TextEncoderAdapter.class, "Encryptor");
// 加密密钥属性键
private static final AttributeKey KEY_SECRETKEY = new AttributeKey(SM4TextEncoderAdapter.class, "SecretKey");
// 块密码工作模式
protected final CipherMode mMode;
// 消息数据块填充类型
protected final PaddingMode mPadding;
// 字符集编码
protected final Charset mCharset;
// 构造函数
public SM4TextEncoderAdapter() {
this(CipherMode.OFB, PaddingMode.PKCS7, StandardCharsets.UTF_8);
}
// 构造函数
public SM4TextEncoderAdapter(CipherMode mode) {
this(mode, PaddingMode.PKCS7, StandardCharsets.UTF_8);
}
// 构造函数
public SM4TextEncoderAdapter(CipherMode mode, PaddingMode padding) {
this(mode, padding, StandardCharsets.UTF_8);
}
/*
功能:构造函数
参数说明:
mode:运算模式,支持ECB、CBC、CFB、OFB(默认)、PCBC
padding:填充模式,支持PKCS7(默认)、ANSIX923、ISO10126、ISO7816、Zeros、None
charset:字符集编码,默认为UTF-8
*/
public SM4TextEncoderAdapter(CipherMode mode, PaddingMode padding, Charset charset) {
if (mode.getValue() > 4) throw new IllegalArgumentException("Unsupported cipher mode!");
mMode = mode;
mPadding = padding;
mCharset = charset;
}
@Override
public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
// 对数据进行对称加密
byte[] Source = message.toString().getBytes(mCharset);
// 获取加密密钥
String SecretKey = (String)session.getAttribute(KEY_SECRETKEY);
if (Utils.IsNullOrEmpty(SecretKey))
{ // 直接发送明文数据
IoBuffer Buffer = IoBuffer.allocate(Source.length + 4);
Buffer.put(Utils.GetBytes(Source.length, ByteOrder.BIG_ENDIAN));
Buffer.put(Source);
Buffer.flip();
out.write(Buffer);
}
else
{ // 对数据进行对称加密
SM4 Encryptor = getEncryptor(session, SecretKey);
byte[] Cipher = Encryptor.TransformFinalBlock(Source, 0, Source.length);
// 发送密文数据
IoBuffer Buffer = IoBuffer.allocate(Cipher.length + 4);
Buffer.put(Utils.GetBytes(Cipher.length, ByteOrder.BIG_ENDIAN));
Buffer.put(Cipher);
Buffer.flip();
out.write(Buffer);
}
}
// 释放资源
@Override
public void dispose(IoSession session) throws Exception
{ // 释放加密器
SM4 Encryptor = (SM4)session.getAttribute(KEY_ENCRYPTOR);
if (Encryptor != null) Encryptor.close();
// 清除属性
session.removeAttribute(KEY_ENCRYPTOR);
session.removeAttribute(KEY_SECRETKEY);
}
// 获取加密器
private SM4 getEncryptor(IoSession session, String SecretKey) throws IOException{
// 获取加密器
SM4 Encryptor = (SM4)session.getAttribute(KEY_ENCRYPTOR);
if (Encryptor == null) {
// 通过密钥派生函数获得对称加密密钥和初始向量
byte[] DerivedVector = SM3.KDF(SecretKey.getBytes("UTF-8"), 32);
// SM4加密器
Encryptor = new SM4(CipherDirection.Encryption, mMode, mPadding);
Encryptor.Initialize(Arrays.copyOfRange(DerivedVector, 0, 16), Arrays.copyOfRange(DerivedVector, 16, 32));
// 设置加密器属性
session.setAttribute(KEY_ENCRYPTOR, Encryptor);
}
return Encryptor;
}
// 获取字符集编码
public Charset getCharset() { return mCharset; }
// 设置加密密钥
public static void setSecretKey(IoSession session, String value){
session.setAttribute(KEY_SECRETKEY, value);
}
// 获取加密密钥
public static String getSecretKey(IoSession session)
{
return (String)session.getAttribute(KEY_SECRETKEY);
}
}
SM4TextCumulativeDecoder.java
/* ----------------------------------------------------------
* 文件名称:SM4TextCumulativeDecoder.java
*
* 作者:秦建辉
*
* QQ:36748897
*
* 博客:http://www.firstsolver.com/wordpress/
*
* 开发环境:
* NetBeans 8.0.2
* JDK 8u66
*
* 版本历史:
* V1.0 2015年11月05日
* 文本流的SM4解码器
------------------------------------------------------------ */
package Com.FirstSolver.Security;
import java.io.IOException;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.AttributeKey;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
public class SM4TextCumulativeDecoder extends CumulativeProtocolDecoder {
// 解码器属性键
private static final AttributeKey KEY_DECRYPTOR = new AttributeKey(SM4TextCumulativeDecoder.class, "Decryptor");
// 解密密钥属性键
private static final AttributeKey KEY_SECRETKEY = new AttributeKey(SM4TextCumulativeDecoder.class, "SecretKey");
// 块密码工作模式
protected final CipherMode mMode;
// 消息数据块填充类型
protected final PaddingMode mPadding;
// 字符集编码
protected final Charset mCharset;
// 构造函数
public SM4TextCumulativeDecoder() {
this(CipherMode.OFB, PaddingMode.PKCS7, StandardCharsets.UTF_8);
}
// 构造函数
public SM4TextCumulativeDecoder(CipherMode mode) {
this(mode, PaddingMode.PKCS7, StandardCharsets.UTF_8);
}
// 构造函数
public SM4TextCumulativeDecoder(CipherMode mode, PaddingMode padding) {
this(mode, padding, StandardCharsets.UTF_8);
}
/*
功能:构造函数
参数说明:
mode:运算模式,支持ECB、CBC、CFB、OFB(默认)、PCBC
padding:填充模式,支持PKCS7(默认)、ANSIX923、ISO10126、ISO7816、Zeros、None
charset:字符集编码,默认为UTF-8
*/
public SM4TextCumulativeDecoder(CipherMode mode, PaddingMode padding, Charset charset) {
if (mode.getValue() > 4) throw new IllegalArgumentException("Unsupported cipher mode!");
mMode = mode;
mPadding = padding;
mCharset = charset;
}
@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
if (in.remaining() > 4) {
in.mark(); // 标记当前位置
byte[] sizeByteArray = new byte[4];
in.get(sizeByteArray);
int size = Utils.ToInt32(sizeByteArray, 0, ByteOrder.BIG_ENDIAN);
if(in.remaining() >= size)
{
byte[] Source = new byte[size];
in.get(Source);
// 获取解密密钥
String SecretKey = (String)session.getAttribute(KEY_SECRETKEY);
if (Utils.IsNullOrEmpty(SecretKey))
{ // 直接输出明文数据
out.write(new String(Source, mCharset));
}
else
{ // 输出解密后的数据
SM4 Decryptor = getDecryptor(session, SecretKey);
out.write(new String(Decryptor.TransformFinalBlock(Source, 0, size), mCharset));
}
if (in.hasRemaining()) return true;
}
else
{ // 回到标记位置
in.reset();
}
}
return false;
}
// 释放资源
@Override
public void dispose(IoSession session) throws Exception {
SM4 Decryptor = (SM4)session.getAttribute(KEY_DECRYPTOR);
if (Decryptor != null) Decryptor.close();
session.removeAttribute(KEY_DECRYPTOR);
session.removeAttribute(KEY_SECRETKEY);
super.dispose(session);
}
// 获取解密器
private SM4 getDecryptor(IoSession session, String SecretKey) throws IOException{
// 获取解密器
SM4 Decryptor = (SM4)session.getAttribute(KEY_DECRYPTOR);
if (Decryptor == null) {
// 通过密钥派生函数获得对称加密私密密钥和初始向量
byte[] DerivedVector = SM3.KDF(SecretKey.getBytes("UTF-8"), 32);
// SM4解密器
Decryptor = new SM4(CipherDirection.Decryption, mMode, mPadding);
Decryptor.Initialize(Arrays.copyOfRange(DerivedVector, 0, 16), Arrays.copyOfRange(DerivedVector, 16, 32));
// 设置解密器属性
session.setAttribute(KEY_DECRYPTOR, Decryptor);
}
return Decryptor;
}
// 获取字符集编码
public Charset getCharset() { return mCharset; }
// 设置解密密钥
public static void setSecretKey(IoSession session, String value) {
session.setAttribute(KEY_SECRETKEY, value);
}
// 获取解密密钥
public static String getSecretKey(IoSession session) {
return (String)session.getAttribute(KEY_SECRETKEY);
}
}