同系列文章:
- 国家商用密码(一)SM2椭圆曲线公钥密码算法
- 国家商用密码(二)C#:基于BouncyCastle实现SM3密码杂凑算法
- 国家商用密码(三)C#:从HashAlgorithm类派生实现SM3密码杂凑算法
- 国家商用密码(四)开放动态库及演示程序
- 国家商用密码(五)基于SM2的软件授权码生成及校验
- 国家商用密码(六)椭圆曲线加密算法密钥生成器
- 国家商用密码(七)在Apache MINA上实现二进制流的SM4编解码器
- 国家商用密码(八)在Apache MINA上实现文本流的SM4编解码器
- 国家商用密码(九)在Apache MINA上实现二进制流数据报文的SM4编解码器
- 国家商用密码(十)在Apache MINA上实现文本流数据报文的SM4编解码器
- 国家商用密码(11)在Netty 5.0.X上实现文本流的SM4编解码器
- 国家商用密码(12)在Netty 4.1.12.Final上实现文本流的SM4编解码器
- 国家商用密码(13)在DotNetty 0.4.5上实现文本流的SM4编解码器
源代码出售:
价格:壹仟元人民币
微信:splashcn
源代码:
SM4TextToMessageCodec.java
/* ---------------------------------------------------------- * 文件名称:SM4TextToMessageCodec.java * * 作者:秦建辉 * * QQ:36748897 * * 博客:http://www.firstsolver.com/wordpress/ * * 开发环境: * NetBeans 8.1 * JDK 8u66 * * 版本历史: * V1.0 2016年02月02日 * 在Netty 5.0.X上实现文本流的SM4编解码器 * ------------------------------------------------------------ */ package Com.FirstSolver.Security; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelPromise; import io.netty.handler.codec.ByteToMessageCodec; import io.netty.util.AttributeKey; import java.io.IOException; import java.nio.ByteOrder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; public class SM4TextToMessageCodec extends ByteToMessageCodec<String> { // 编码器 private static final AttributeKey<SM4> KEY_ENCRYPTOR = AttributeKey.valueOf(SM4TextToMessageCodec.class, "Encryptor"); // 解码器 private static final AttributeKey<SM4> KEY_DECRYPTOR = AttributeKey.valueOf(SM4TextToMessageCodec.class, "Decryptor"); // 通信密钥 private static final AttributeKey<String> KEY_SECRETKEY = AttributeKey.valueOf(SM4TextToMessageCodec.class, "SecretKey"); // 构造函数 public SM4TextToMessageCodec() { this(CipherMode.OFB, PaddingMode.PKCS7, StandardCharsets.UTF_8); } // 构造函数 public SM4TextToMessageCodec(CipherMode mode) { this(mode, PaddingMode.PKCS7, StandardCharsets.UTF_8); } // 构造函数 public SM4TextToMessageCodec(CipherMode mode, PaddingMode padding) { this(mode, padding, StandardCharsets.UTF_8); } /* 功能:构造函数 参数说明: mode:运算模式,支持ECB、CBC、CFB、OFB(默认)、PCBC padding:填充模式,支持PKCS7(默认)、ANSIX923、ISO10126、ISO7816、Zeros、None charset:字符集编码 */ public SM4TextToMessageCodec(CipherMode mode, PaddingMode padding, Charset charset) { if (mode.getValue() > 4) throw new IllegalArgumentException("Unsupported cipher mode!"); mMode = mode; mPadding = padding; mCharset = charset; } /* 功能:构造函数 参数说明: mode:运算模式,支持ECB、CBC、CFB、OFB(默认)、PCBC padding:填充模式,支持PKCS7(默认)、ANSIX923、ISO10126、ISO7816、Zeros、None charset:字符集名称 */ public SM4TextToMessageCodec(CipherMode mode, PaddingMode padding, String charset) { this(mode, padding, Charset.forName(charset)); } // 编码 @Override protected void encode(io.netty.channel.ChannelHandlerContext ctx, String msg, io.netty.buffer.ByteBuf out) throws Exception { // 将字符串转换为字节数组 byte[] Source = msg.getBytes(mCharset); // 获取加密密钥 String SecretKey = ctx.attr(KEY_SECRETKEY).get(); if (!Utils.IsNullOrEmpty(SecretKey)) { // 对数据进行对称加密 SM4 Encryptor = getEncryptor(ctx, SecretKey); Source = Encryptor.TransformFinalBlock(Source, 0, Source.length); } out.writeBytes(Utils.GetBytes(Source.length, ByteOrder.BIG_ENDIAN)); out.writeBytes(Source); ctx.flush(); } // 解码 @Override protected void decode(io.netty.channel.ChannelHandlerContext ctx, io.netty.buffer.ByteBuf in, List<Object> out) throws Exception { if (in.readableBytes() > 4) { in.markReaderIndex(); int Size = in.readInt(); if(in.readableBytes() >= Size) { byte[] Source = new byte[Size]; in.readBytes(Source); // 获取解密密钥 String SecretKey = ctx.attr(KEY_SECRETKEY).get(); if (Utils.IsNullOrEmpty(SecretKey)) { // 直接输出明文数据 out.add(new String(Source, mCharset)); } else { // 输出解密后的数据 SM4 Decryptor = getDecryptor(ctx, SecretKey); out.add(new String(Decryptor.TransformFinalBlock(Source, 0, Size), mCharset)); } } else { // 回到标记位置 in.resetReaderIndex(); } } } // 释放资源 @Override public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { // 释放加密器 SM4 Encryptor = ctx.attr(KEY_ENCRYPTOR).get(); if (Encryptor != null) Encryptor.close(); // 释放解密器 SM4 Decryptor = ctx.attr(KEY_DECRYPTOR).get(); if (Decryptor != null) Decryptor.close(); // 移去属性键 ctx.attr(KEY_ENCRYPTOR).remove(); ctx.attr(KEY_DECRYPTOR).remove(); ctx.attr(KEY_SECRETKEY).remove(); } // 获取加密器 private SM4 getEncryptor(io.netty.channel.ChannelHandlerContext ctx, String SecretKey) throws IOException { SM4 Encryptor = ctx.attr(KEY_ENCRYPTOR).get(); if (Encryptor == null) { Encryptor = new SM4(CipherDirection.Encryption, mMode, mPadding); byte[] DerivedVector = SM3.KDF(SecretKey.getBytes("UTF-8"), 32); Encryptor.Initialize(Arrays.copyOfRange(DerivedVector, 0, 16), Arrays.copyOfRange(DerivedVector, 16, 32)); ctx.attr(KEY_ENCRYPTOR).set(Encryptor); } return Encryptor; } // 获取解密器 private SM4 getDecryptor(io.netty.channel.ChannelHandlerContext ctx, String SecretKey) throws IOException { SM4 Decryptor = ctx.attr(KEY_DECRYPTOR).get(); if (Decryptor == null) { Decryptor = new SM4(CipherDirection.Decryption, mMode, mPadding); byte[] DerivedVector = SM3.KDF(SecretKey.getBytes("UTF-8"), 32); Decryptor.Initialize(Arrays.copyOfRange(DerivedVector, 0, 16), Arrays.copyOfRange(DerivedVector, 16, 32)); ctx.attr(KEY_DECRYPTOR).set(Decryptor); } return Decryptor; } // 获取字符集编码 public Charset getCharset() { return mCharset; } // 设置加密密钥 public static void setSecretKey(io.netty.channel.ChannelHandlerContext ctx, String key) { ctx.attr(KEY_SECRETKEY).set(key); } // 获取加密密钥 public static String getSecretKey(io.netty.channel.ChannelHandlerContext ctx) { return ctx.attr(KEY_SECRETKEY).get(); } // 运算模式,支持ECB、CBC、CFB、OFB(默认)、PCBC private CipherMode mMode; // 填充模式,支持PKCS7(默认)、ANSIX923、ISO10126、ISO7816、Zeros、None private PaddingMode mPadding; // 字符集编码,默认为UTF-8 private final Charset mCharset; }