(一)敏感信息混淆
2018-09-18 06:34:47来源:博客园 阅读 ()
最近网上出现的安全事故很多,最惨的莫过于那场酒店事件,因此项目整改也需要对用户的敏感信息进行脱敏,由于前期的项目并没有规划这一模块,为了满足安全规范达到上线标准,需要对项目进行改造。
改造方案
1. 不能采用手动encode/decode的方式(避免在某个地方忘记encode/decode了)
2. 非侵入性改造,后续的coding的时候无需在费心思考虑
方案1: 从数据层入手,在提交数据库前对敏感字段进行encode,在取得数据集后对结果集的敏感字段进行decode。
项目中选择mybatis为中间件,因此可以使用mybatis拦截器,方案实现起来简单,符合条件2,但却会带来关键问题:在单业务编写时基本没有问题,但是在多业务关联的时候却会对关联的字段有影响,需要在手动encode,不符合条件1,因此方案被pass。
方案2: 从控制层入手,在接收客户端提交的数据时对敏感字段进行encode,在response序列化对象时对敏感字段进行decode。
该方案能保证敏感字段在业务逻辑实现过程中都是混淆的,后续也无需关注哪个对象的哪个字段是需要encode/decode,满足改造方案。
实现方案
1. 定义敏感字段类型,由于混淆后的字段类型均可以为字符串,因此我们可以仿造String类型来进行定义(由于String类是final,因此不考虑继承的方式)
/** * @author zhangqiuyang * Created on 2018/8/17. */ public class SecretString implements java.io.Serializable, Comparable<String>, CharSequence { @Setter @Getter private String value; public SecretString(String value) { this.value = value; } /** * Returns the length of this character sequence. The length is the number * of 16-bit <code>char</code>s in the sequence. * * @return the number of <code>char</code>s in this sequence */ @Override public int length() { return value.length(); } /** * Returns a string representation of the object. In general, the * {@code toString} method returns a string that * "textually represents" this object. The result should * be a concise but informative representation that is easy for a * person to read. * It is recommended that all subclasses override this method. * <p> * The {@code toString} method for class {@code Object} * returns a string consisting of the name of the class of which the * object is an instance, the at-sign character `{@code @}', and * the unsigned hexadecimal representation of the hash code of the * object. In other words, this method returns a string equal to the * value of: * <blockquote> * <pre> * getClass().getName() + '@' + Integer.toHexString(hashCode()) * </pre></blockquote> * * @return a string representation of the object. */ @Override public String toString() { return value; } /** * Returns the <code>char</code> value at the specified index. An index ranges from zero * to <tt>length() - 1</tt>. The first <code>char</code> value of the sequence is at * index zero, the next at index one, and so on, as for array * indexing. * * <p>If the <code>char</code> value specified by the index is a * <a href="{@docRoot}/java/lang/Character.html#unicode">surrogate</a>, the surrogate * value is returned. * * @param index the index of the <code>char</code> value to be returned * @return the specified <code>char</code> value * @throws IndexOutOfBoundsException if the <tt>index</tt> argument is negative or not less than * <tt>length()</tt> */ @Override public char charAt(int index) { return value.charAt(index); } /** * Returns a <code>CharSequence</code> that is a subsequence of this sequence. * The subsequence starts with the <code>char</code> value at the specified index and * ends with the <code>char</code> value at index <tt>end - 1</tt>. The length * (in <code>char</code>s) of the * returned sequence is <tt>end - start</tt>, so if <tt>start == end</tt> * then an empty sequence is returned. * * @param start the start index, inclusive * @param end the end index, exclusive * @return the specified subsequence * @throws IndexOutOfBoundsException if <tt>start</tt> or <tt>end</tt> are negative, * if <tt>end</tt> is greater than <tt>length()</tt>, * or if <tt>start</tt> is greater than <tt>end</tt> */ @Override public CharSequence subSequence(int start, int end) { return value.subSequence(start, end); } /** * Compares this object with the specified object for order. Returns a * negative integer, zero, or a positive integer as this object is less * than, equal to, or greater than the specified object. * * <p>The implementor must ensure <tt>sgn(x.compareTo(y)) == * -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>. (This * implies that <tt>x.compareTo(y)</tt> must throw an exception iff * <tt>y.compareTo(x)</tt> throws an exception.) * * <p>The implementor must also ensure that the relation is transitive: * <tt>(x.compareTo(y)>0 && y.compareTo(z)>0)</tt> implies * <tt>x.compareTo(z)>0</tt>. * * <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt> * implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for * all <tt>z</tt>. * * <p>It is strongly recommended, but <i>not</i> strictly required that * <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>. Generally speaking, any * class that implements the <tt>Comparable</tt> interface and violates * this condition should clearly indicate this fact. The recommended * language is "Note: this class has a natural ordering that is * inconsistent with equals." * * <p>In the foregoing description, the notation * <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical * <i>signum</i> function, which is defined to return one of <tt>-1</tt>, * <tt>0</tt>, or <tt>1</tt> according to whether the value of * <i>expression</i> is negative, zero or positive. * * @param o the object to be compared. * @return a negative integer, zero, or a positive integer as this object * is less than, equal to, or greater than the specified object. * @throws NullPointerException if the specified object is null * @throws ClassCastException if the specified object's type prevents it * from being compared to this object. */ @Override public int compareTo(String o) { return value.compareTo(o); } /** * 解密后的值 * * @return */ public String decryptValue() { return SecurityUtil.decryptString(value); } }
2. 定义敏感字段类型的序列化器
/** * @author zhangqiuyang * Created on 2018/8/17. */ @JsonComponent public class SecretStringJsonCombinedSerializer { /** * 密文序列化 */ public static class SecretStringJsonSerializer extends JsonSerializer<SecretString> { /** * 重写序列化SecretString类型字段 * * @param secretString * @param jsonGenerator * @param serializerProvider * @throws IOException */ @Override public void serialize(SecretString secretString, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(secretString.decryptValue()); } } /** * 密文反序列化 */ public static class SecretStringJsonDeserializer extends JsonDeserializer<SecretString> { @Override public SecretString deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser); return new SecretString(SecurityUtil.encryptString(((TextNode) treeNode).asText())); } } }
综上,改造基本完成。
github:https://github.com/zqyx5201/SecretStringTest
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 程序员发面试短信,HR十天后才回复信息还被拒:你算什么东西 2020-05-28
- Java 注解 2020-05-25
- Spring Security 中如何快速查看登录 IP地址等信息?一招搞 2020-05-07
- 小屋信息Java实习面试(offer到手含面试经验及答案) 2020-05-06
- Thymeleaf+SpringBoot+Mybatis实现的齐贤易游网旅游信息管理 2020-04-26
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash