使用ELGmal算法为跨系统调用保驾护航

为什么我们需要加密算法?

一般在开发过程中,我们为了保证敏感数据的安全性,才会对操作传输的数据进行加密,从而提高整个系统的安全性。

比如,客户端和服务端的数据交互传输,服务端将从数据库查询出来的数据通过加密的方式传递给客户端,客户端也将用户提交的数据加密后提交给服务端,两边都通过对应的解密规则进行解密,这样在数据传输的过程中,一些别有用心的人试图通过Fiddler这样的工具进行数据抓包而试图获得一些隐私数据将变得极其艰难,这也就达到了我们对数据安全性提升目的。

周一的时候,我接到了一个需求,某领导想要通过系统A免密跳转到系统B,因为领导觉得再去系统B输入一次用户名、密码、验证码实在是太繁琐了,尤其是在他有大量的审批工作要做的情况下。

如果两个系统统一做的CAS单点登录的前期框架性工作,这件事可以说根本不叫事,但是这个系统A和系统B都是近十年的老系统,肯定是没有这样的条件的,于是如何将免密登录的安全性提高就成了这个需求的重中之重了。

整体思路

先抛开加密本身,我先说一下我对这个需求的整体考虑:

1.jpg

具体步骤是:

  1. 系统A发起免密登录的请求
  2. 系统B通过加密算法得到密钥(公钥和私钥--非对称加密)
  3. 系统B将加密后的公钥返回给系统A
  4. 系统A解密公钥后使用公钥对数据进行加密并提交给系统B
  5. 系统B拿到密文后用私钥进行解析
  6. 解析成功就执行免密登录,失败就放弃该次操作。

整体的架构思路大致就是如此,这样就算别有用心的人使用抓包工具对这两次API请求都进行截获,也很难获取到真实的数据信息了。

加密算法选型

用什么算法?

众所周知,加密方式有两个常用的大方向,一个是对称加密,一个是非对称加密。

对称加密:用相同的密钥对原文进行加密和解密,通信双方共用一个密钥。

  • 加密过程:原文 + 密钥 => 密文
  • 解密过程:密文 - 密钥 => 原文

非对称加密:有两个密钥,即公钥(Public Key)和私钥(Private Key),对数据进行加密和解密使用不同的密钥。使用公钥进行加密,使用私钥进行解密。

  • 加密过程:原文 + 公钥 => 密文
  • 解密过程:密文 - 私钥 => 原文

对称加密的缺点:

​ 对称加密算法的缺点:无法确保密钥被安全传递。如果密钥被截获,则整个加密密文都是不安全的。

对称加密的特点:

​ 采用非对称加密算法即使第三方在网络上截获到密文,但其无法获得接收方的私钥,也就无法对密文进行解密,作为接收方务必保证自己私钥的安全,所以非对称加密技术解决了密钥传输过程的安全性问题。

好了,看到这里,大方向肯定定下来了,非对称加密跑不了了,然后我们看看非对称加密有哪些加密算法呢?

非对称加密算法类型:

RSA、Elgamal、背包算法、Rabin、Diffie-Hellman、ECC(椭圆曲线加密算法)。
使用最广泛的是RSA算法,Elgamal是另一种常用的非对称加密算法,考虑到成本和学习曲线的问题,我这次选择了ElGamal加密算法,因为两点:

  1. ElGamal算法不是双向加解密的,RSA是双向加解密的。

    双向加解密:公钥、私钥都可以进行加密和解密(公钥加密需要私钥解密、私钥加密需要公钥解密)

  2. ElGamal我在线查了半天也没找到解密工具,而RSA我查到了(当然,不确定其是否可用)......

正所谓树大招风,与其使用RSA这种最常见的非对称加密,我还是决定选择一些相对没那么热门的加密方式,这样一些常见的在线破解网站也不会提供简单的破解渠道,从而进一步增加数据的安全性,但是冷门,也带来了一些冷门固有的问题,这个后面再说。

ElGamal算法在使用中的一些问题

1.Illegal key size or default parameters

当你找到一些ElGamal或者RSA的既有算法的DEMO后,兴高采烈的Run起它的main方法后,你有很大概率会遇到这个问题,一脸懵逼的你不用慌张,这是由于美帝的出口限制导致的加密算法Key长度的限制,具体原因:

每个国家,尤其是美国,对涉及密码的软件产品控制非常严格,在美国国内,很多密码算法长度都作了限制,而且某些算法在某些国家没有申请专利,可以"滥"用,而在某些国家却做了明确限制,不准使用,如此前提下,Sun必须按照惯例行事。

套用中国一句老话:上有政策,下有对策。Oracle也单独的放出了关于解决这个问题的无政策限制文件(local_policy.jar和US_export_policy.jar),我们只要下载对应JDK版本的文件并覆盖到指定路径(%JDK_Home%\jre\lib\security)下即可。

2.JDK并不直接支持Elgamal算法

这就是冷门带来的问题了,你并不能直接在JDK中使用ElGamal的算法支持,所以必须要引入两个jar包:

  1. bouncycastle 下载地址:

    http://www.bouncycastle.org/latest_releases.html

  2. commons-codec 下载地址:

    http://archive.apache.org/dist/commons/codec/binaries/

这两个Jar包一个是对ElGamal算法本身提供支持的,另一个是对Base64提供支持的,都需要引入到项目中去。

3.ElGamal KeyFactory not available

在实际使用ElGamal算法的时候,我们不太可能只在一端使用公钥和私钥,这就面临着我们需要在另一个平台使用公钥加密的算法,常见的公钥加密算法是这样写的:

public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{
        
        //实例化密钥工厂
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公钥
        //密钥材料转换
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);
        //产生公钥
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);
        
        //数据加密
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

当你在同一个程序中这样写公钥加密算法是没有问题的,因为你在启动main方法的时候,已经做好了initKey的相关工作了,但是你在另一个平台直接调用该方法则会报出错误:

java.security.NoSuchAlgorithmException: ElGamal KeyFactory not available

其实这也是冷门后遗症,因为JDK并没有实现ElGamal算法,所以不做初始化就直接用KeyFactory调用对应算法的KeyFactory实例,是肯定会报错的,解决方法就是自己做好初始化,走到天下都不怕:

    public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{
       //加入对BouncyCastle支持
        Security.addProvider(new BouncyCastleProvider());
        AlgorithmParameterGenerator apg=AlgorithmParameterGenerator.getInstance(KEY_ALGORITHM);
        //初始化参数生成器
        apg.init(KEY_SIZE);
        // 实例化密钥生成器
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_ALGORITHM);
       //实例化密钥工厂
        KeyFactory keyFactory=KeyFactory.getInstance(KEY_ALGORITHM);
        //初始化公钥
        //密钥材料转换
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(key);
        //产生公钥
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);    
        //数据加密
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

4.Cannot find any provider supporting ElGamal

这个问题就不是每个人都会遇到了,由于我是给服务端的同事写方法让他们各自调用自己那端需要的加密方法,所以我考虑了将他们需要的类封装成jar包的想法,于是我就将源码各自分离后,进行了基础的封装,然后通过Build FatJar将数据封装成jar包调用,测试调用的项目也顺利的引入了,一切就绪,运行main方法,然后就报错了.....

java.security.NoSuchAlgorithmException: Cannot find any provider supporting ElGamal

不支持Elgaml???明明已经加上了对应的初始化方法了啊,怎会不执行呢?

其实这里,不是不执行初始化的方法,而是所需的第三方jar在jar包内部并没有被正常加载导致的,我检查了一下jar的MANIFEST.MF文件发现合并打包时第三方丢失了Export-Package和Include-Resource对于第三方jar包的描述,解决方案可以查看:

https://www.cnblogs.com/skyme/articles/2316457.html

而我这个项目由于只需要两个jar包,所以我的解决方案是单独导出我的jar包,然后在新项目中独立引入我导出的jar包和bouncycastle包以及codec包,这样一切都可以正常执行了。

总结

以上就是我使用ElGamal算法时遇到的一些问题,希望大家在使用的过程中尽量避开这些问题,也为自己做个记录。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容