龙空技术网

Java单例模式很容易破解,一旦破解就会造成系统性风险

架构师风吹哨 1122

前言:

当前看官们对“java防破解”可能比较关切,小伙伴们都想要知道一些“java防破解”的相关资讯。那么小编同时在网上汇集了一些关于“java防破解””的相关文章,希望我们能喜欢,咱们快快来学习一下吧!

Java的单例模式,其实破解起来很方便,一旦破解单例就会失效,变成复例模式,一般有两种方式破解。

第一:反射方式破解,这种方式通过反射获取类,然后调用该类的构造函数创建对象,所以我们只需要在构造函数上做限制就好。把绿色部分的注释去掉,就可以防止单例破解了。

  public class Singleton {        private static Singleton instance;        private Singleton() {          	//if(instance != null) {throw new RuntimeException("救命啊,有坏蛋想破我");}        }        public static synchronized Singleton getInstance() {            if (instance == null) {                instance = new Singleton();            }            return instance;        }    }

开始破解

 public static void main(String[] args) throws Exception {        //反射获取单例类        Class<Singleton> claz = (Class<Singleton>) Class.forName("Singleton");        //通过反射获得原本私有的无参构造器        Constructor<Singleton> c = claz.getDeclaredConstructor(null);        //关闭安全检查        c.setAccessible(true);        //通过构造器实例化对象        Singleton s3 = c.newInstance();        Singleton s4 = c.newInstance();        System.out.println(s3);        System.out.println(s4);    }

运行结果:

singleton.Singleton@6d06d69csingleton.Singleton@7852e922

方式二:序列化方式,这种方式问题主要是发生在反序列化的环节,每次反序列化都会生成新的对象,如果我们再生成新的对象时候让他返回老的对象就可以防止了,readResolve方法做控制就好

public class Singleton implements Serializable {        private static Singleton instance;        private Singleton() {        }        public static synchronized Singleton getInstance() {            if (instance == null) {                instance = new Singleton();            }            return instance;        }    		//private Object readResolve(){			//	return instance;			//}    }

开始破解:

public static void main(String[] args) throws Exception {        Singleton s1 = Singleton.getInstance();        System.out.println(s1);          //先序列化        ByteArrayOutputStream os = new ByteArrayOutputStream();        ObjectOutputStream oos = new ObjectOutputStream(os);        oos.writeObject(s1);				//反序列化        InputStream is = new ByteArrayInputStream(os.toByteArray());        ObjectInputStream ois = new ObjectInputStream(is);        Singleton s2 = (Singleton) ois.readObject();        System.out.println(s2);            }

标签: #java防破解