美文网首页
Python调用Java接口——数据加密解密

Python调用Java接口——数据加密解密

作者: AlexDM | 来源:发表于2016-12-31 19:59 被阅读561次

    前段时间写了一个python程序,涉及http请求和数据的加密解密,终于完成了,虽然经历很长的时间,填了很多坑,但是值得记录一下,分享出来。由于是在简书的第一篇文章,理应是满满的干货。

    这个需求的背景是这样的,需要把公司的用户加以区分,分为内部用户和外部用户,通过什么来区分的,当然是通过手机号比较简单容易了,所以就定下来用手机号区分。但是获取手机号对于公司的高层来说,可能觉得有点安全隐患,为了保险就对数据进行加密解密,方法就是请求方发送请求的时候,把公钥发过去,同时也有其他的一些参数,对方根据公钥加密,返回数据,请求方再根据私钥解密。【后来和其他同事说起这个事情的时候,他说这样好像并没有什么卵用,因为是自己发送公钥,收到数据自己再解密,如果其他人知道了这个方法和传输的参数,他也可以获取到数据,我感觉真的是这么回事啊。】

        现在来说一下这个曲折的过程。
    

    1、调用java接口

    2、确定使用加密的算法

    3、分段解密

    具体过程是这样的:
    1、对于http请求来说,相对简单一些,在网上可以找到现成的例子,需要注意的就是把header里面的内容写对,Content-type,Accept要注意,我这边接收的是json格式的数据,所以accept是application/json,下面是我在网上搜的一个例子。

    
    #!/usr/bin/env python
    #coding=utf8
     
    import httplib, urllib
     
    httpClient = None
    try:
        params = urllib.urlencode({'name': 'tom', 'age': 22})
        headers = {"Content-type": "application/x-www-form-urlencoded"
                        , "Accept": "text/plain"}
     
        httpClient = httplib.HTTPConnection("localhost", 80, timeout=30)
        httpClient.request("POST", "/test.php", params, headers)
     
        response = httpClient.getresponse()
        print response.status
        print response.reason
        print response.read()
        print response.getheaders() #获取头信息
    except Exception, e:
        print e
    finally:
        if httpClient:
            httpClient.close()
    
    

    如果接口可以调通,那么status应该是200,reason是OK,如果出现其他的状态码,就要具体分析了。

    2、一般很快就可以调通了,之后就是处理返回的数据。对于加密解密有的说了,我在网上搜了一下,对于python有很多的模块可以操作,但是最后选择了M2Crypto进行操作。【由于服务器python版本的限制吧,本地可以使用的,在服务器上却不可以使用】之前尝试使用RSA来操作,但是由于我给接口传的PublicKey的类型、长度有问题,导致一直无法返回数据,接口接受的PublicKey是一串字符串,而我曾经把RSA生成的Publickey整体传给了对方,后来一起调的时候,各自测试发现了参数类型不一致,以及PublicKey的长度不一致,这个时候我觉得可能是参数key的算法不一致导致的长度不一致,中间也换了其他的模块,不过失败了,最后选择用openssl产生PublicKey,PrivateKey,这个时候的PublicKey和对方java产生的长度一样了,终于可以看到返回的数据了。

    下面是在python中使用openssl产生公钥和私钥

    os.system('rm ./privatekey.pem ./publickey.pem')
    os.system('openssl genrsa -out ./privatekey.pem')
    os.system('openssl rsa -pubout -in ./privatekey.pem -out ./publickey.pem')
    

    不过,我还是高兴的太早了,数据是返回了,但是还没有解密啊。解密也是很头疼的,本以为用函数就可以解密了,结果还是调了半天,中间还有一个环节,就是用base64进行编码,这又涉及了解码的过程。所以,我拿到数据之后先进行解码,解码之后再解密。

    当然获取的数据需要转换一下格式,json字符串转换为python可以处理的字典
    data = = json.loads(response.read())
    
    base64这个库不需要安装,引入就可以了,我最开始还傻乎乎的安装
    data = base64.b64decode(data)
    

    你以为现在就可以解密了么,too young too simple,你知道对方是根据什么模式进行填充加密块么,也就是padding参数是什么,这个参数有四个值:no_padding,pkcs1_padding,sslv23_padding,pkcs1_oaep_padding,当我问对方的时候,对方一脸懵B的看着我,我只能挨个试一下了,反正也就四个么,试下来是pkcs1_padding,可能默认的就是这个吧,具体没有深究。

    3、确定好这个参数之后,就是激动人心的时刻了,运行之后终于可以看到人类可以看懂的数据了,可是依然有一个问题,当我修改了一个参数之后,竟然又报错了,错误没有记下来,反正就是数据比较大的意思,这其实是超过解密算法的能力了,对于1024位的秘钥,加密字节最长为117,解密字节最长为128,所以需要分段解密才可以。接下来就是分段解密了,这个网上也可以搜到。

    def decodeSplit(message,clientPriKey):
            """
           消息在传送过来之前是经过base64加密的,所以要先进行base64解密后才进行RSA分段解密
           64为key.size/8,密钥长度为512
           """
            message = base64.b64decode(base64.b64decode(message))
            count = len(message)
            if count>64:
                    jiemi=""
                    index=0
                    while index<count:
                            i = 64 if count-index>64 else count-index
                            submsg = message[index:index+i]
                            index+=i
                            j = rsa.decrypt(submsg,clientPriKey)
                            jiemi+=j
                    return jiemi
            else:
                    jiemi = rsa.decrypt(message,clientPriKey)
                    return jiemi
    

    这个弄好了就可以看到完整的数据了,终于大功告成。

    以下为参考资料,可能不完整,如果遗漏请谅解,如有侵权,请联系。

    参考资料:
    1、http://hgoldfish.com/blogs/article/57/
    2、http://betazk.github.io/2014/10/python%E8%BF%9E%E6%8E%A5.net%E7%AB%AF%E9%81%87%E5%88%B0%E7%9A%84%E4%B8%80%E4%BA%9B%E9%97%AE%E9%A2%98%E5%9B%9E%E9%A1%BE/
    3、http://blog.csdn.net/nyist327/article/details/48352253

    相关文章

      网友评论

          本文标题:Python调用Java接口——数据加密解密

          本文链接:https://www.haomeiwen.com/subject/qufbvttx.html