接口测试 robotframework 接口测试 +RSA 加密

xizeng · 2017年11月29日 · 最后由 yyy 回复于 2017年12月22日 · 3301 次阅读

首先,实现 RSA 加密,需要用到 pycrypto 这个库,这个库又依赖 openssl,所以需要先下载 openssl,具体教程可以参考http://bbs.csdn.net/topics/392193545?page=1
安装完成后就可以安装 pycrypto, pip install pycrypto ,如果报的错是 VC++ ,那么就现在安装 vc++ 在安装 pycrypto ,https://www.microsoft.com/en-us/download/details.aspx?id=44266
java 版的加密函数如下:

public static String sign(byte[] data, final String privateKey) throws Exception {
    byte[] keyBytes = Base64Utils.decrypt(privateKey);
    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
    Signature signature = Signature.getInstance("MD5withRSA");
    signature.initSign(privateK);
    signature.update(data);
    return Base64Utils.encrypt(signature.sign());
}

具体的 python 函数如下:

import hashlib
import base64
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA
from Crypto.Hash import MD5

priKey = '''-----BEGIN RSA PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAN8M7oBSoZOzAoxL3tmzku/ZTtQn/BBqfe8jj0GZeFKh0IY8qDpFrNONzxp4S+TH4xCXYyEFkkEIcS9SKMCbqba
-----END RSA PRIVATE KEY-----'''

def sign(self, signdate):
        reload(sys)
        sys.setdefaultencoding('utf-8')
        h=MD5.new(signdate)
        signer = PKCS1_v1_5.new(RSA.importKey(priKey))
        signn = signer.sign(h)
        signn=base64.urlsafe_b64encode(signn)
        return signn

priKey 是私钥,每个公司的私钥是不一样的。

在 robotframework 中导入自己写的 py 文件就可以调用 sign 了,但是这个签名结果后面多了一个 ‘=’,需要加一步替换,把=替换为空,

在 python 内置的 base64 库中,可以直接进行编码,base64.b64encode,但是编码后的数据可能会出现 ‘+’ 或者 ‘/’,这在 rul 中是不能作为参数的,而 base64.rulsafe_b64encode 则把 ‘+’ 或 ‘/’ 转换成 ‘-‘或者’_‘。具体编码函数看需求,如果是做 url 则必须用 urlsafe
Base64 是一种通过查表的编码方法,不能用于加密,即使使用自定义的编码表也不行。
Base64 适用于小段内容的编码,比如数字证书签名、Cookie 的内容等。
由于=字符也可能出现在 Base64 编码中,但=用在 URL、Cookie 里面会造成歧义,所以,很多 Base64 编码后会把=去掉,这也就是上面提到的为什么多了一个’=‘。

get。
接口测试第一步是创建 session,第一个参数是 alias,也就是命名,识别用的,第二个参数为 url,第二行为 rsa 加密,看需要,第五行是创建头文件(具体参数看公司需求),第六行是参数变量,第八行即为连接 api,第一个参数是 alias,需要跟上面的保持一致,第二个参数是 uri,第三第四为头文件跟参数变量

post
post 跟 get 基本一致,在 post 需要注意接口传参是 json 格式还是普通格式(跟 get 一样),如果是 json 格式,则 post request 后面应该用 data,如果是普通格式则用 params

data 如下,其实也就是把 params 改成 data

params 与 data 还有一个区别就是签名,使用 params 时,签名需要把所有参数附上,而且得按字母排序,用 data 时就不用加上参数。具体如下:

/public/corporate/fund/proposa?fundCode=${fundCode}&investmentAmount=${investmentAmount}&x-api-key=I&x-api-timestamp=${timestamp}&x-api-version=2.0
/public/corporate/fund?x-api-key=I&x-api-timestamp=${timestamp}&x-api-version=2.0

在我这里,rsa 加密,如果参数是 json 格式,那么在加密的时候是不需要加参数的,参数直接在 post request 用 data 进行传输,数据在这里有一个需要注意的地方,那就是

{
  "accountNumber": "IF2016070100000044",
  "corporateUserCode": 0,
  "investorPayId": 28,
  "merchantNumber": "IF2017112100003",
  "password": "if123",
  "payMethod": 0,
  "purchaseFunds": [
    {
      "currency": "156",
      "fundCode": "0408",
      "investmentAmount": 10
    }
  ],
  "riskConfirmed": 1
}

json 里面有没有出现数组,即有没有出现中括号’[’,‘ ]‘,有的话,需要先进行 create dictionary 之后再进行 create list,这样传输的数据才能正确。

时间戳:
获取当前时间的时间戳为:${date} get time epoch;get time 是内置库 BuiltIn 的关键字
把时间转成时间戳:${date} Convert Date 2017-11-22 10:00:00 epoch;Convert Date 是 Date Time 库的关键字
把时间戳转成时间:${date} get time ‘空一格’ ${time};注意在空一格那位置上空一格。。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 4 条回复 时间 点赞

学习了

@xizeng 你好,请问我用这个代码加密一个字符串,为什么会报错呢?

Traceback (most recent call last):
  File kkk.py", line 25, in <module>
    kk = sign(signdate)
  File "kkk.py", line 19, in sign
    signer = PKCS1_v1_5.new(RSA.importKey(priKey))
  File "/venv/lib/python2.7/site-packages/Crypto/PublicKey/RSA.py", line 660, in importKey
    der = binascii.a2b_base64(b('').join(lines[1:-1]))
binascii.Error: Incorrect padding
import hashlib
import base64
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA
from Crypto.Hash import MD5
import sys

priKey = '''-----BEGIN RSA PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAN8M7oBSoZOzAoxL3tmzku/ZTtQn/BBqfe8jj0GZeFKh0IY8qDpFrNONzxp4S+TH4xCXYyEFkkEIcS9SKMCbqba
-----END RSA PRIVATE KEY-----'''

signdate = "1234567890123456"

def sign(signdate):
        # reload(sys)
        # sys.setdefaultencoding('utf-8')
        h=MD5.new(signdate)
        signer = PKCS1_v1_5.new(RSA.importKey(priKey))
        signn = signer.sign(h)
        signn=base64.urlsafe_b64encode(signn)
        return signn


kk = sign(signdate)
yyy 回复

我这里的 prikey 是公司的,我提交上来的时候已经被我删除了一大半,所以这个是错误的。你要有自己的正确的 prikey,才能跑得过,还有得是 JAVA 版

xizeng 回复

噢..这样啊..😵

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册