Http协议与请求, Post请求与Get请求的区别,Base64和URL编码,md5,sha-1加密,对称和非对称加密,支付宝微信第三方支付

本文详细介绍了HTTP协议中的POST请求方式,包括与GET请求的区别、使用场景及注意事项。同时,还探讨了如何在Android环境中实现POST请求,涉及上传键值对、JSON数据、单个和多个文件等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Http协议与请求
Post请求

    Post请求与Get请求的区别
        Get请求的参数是直接放在url后面的,而Post请求是放在请求体中的
        Get请求参数的长度会根据浏览器的不同实现有一定限制,而Post请求参数长度没有限制
        Get请求方便测试,直接输入地址即可,而Post请求不方便测试,需要借助代码或者工具进行发送
        Get请求和Post请求没有本质的区别,只是定义上的区别,比如如果你非要将get方式的参数放在请求体中,那么服务器也是可以接收处理的,同样,你也可以将post方式的参数拼在url后面
    Post请求的使用场景
        使用Post请求上传键值对
        使用Post请求上传json串
        使用Post请求上传单个文件
        使用Post请求上传多个文件

    使用Post方法上传键值对,代码如下:

    public void asyncPost(String url,HashMap<String, String> params,TextHttpResponseHandler responseHandler){
        RequestParams requestParams = new RequestParams(params);
        asyncHttpClient.post(url, requestParams, responseHandler);
    }
    /**
     * post提交key-value
     * @param url2
     */
    private void postKeyValue(String url) {
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("username", "俊哥");
        params.put("password", "111");
        HttpHelper.get().asyncPost(url, params, new TextHttpResponseHandler() {
            @Override
            public void onSuccess(int arg0, Header[] arg1, String text) {
                tv_result.setText(text);
            }
            @Override
            public void onFailure(int arg0, Header[] arg1, String arg2, Throwable arg3) {

            }
        });
    }

    使用Post方式上传文件,代码如下:

    public void asyncUploadFile(String url, String key, File file,TextHttpResponseHandler responseHandler) {
        RequestParams requestParams = new RequestParams();
        try {
            requestParams.put(key, file);
            asyncHttpClient.post(url,requestParams , responseHandler);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    private void uploadFile() {
        try {
            File file = new File(Environment.getExternalStorageDirectory()+"/dog.jpg");
            HttpHelper.get().asyncUploadFile(upload, "file", file, new TextHttpResponseHandler() {
                @Override
                public void onSuccess(int arg0, Header[] arg1, String text) {
                    tv_result.setText(text);
                }
                @Override
                public void onFailure(int arg0, Header[] arg1, String arg2, Throwable arg3) {

                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    Post请求相关注意事项:
        传递中文参数问题,Get请求同样需要注意,需要对url进行编码,对应的类有URLEncoder和URLDecoder,否则会乱码,当然很多第三方http库已经处理该问题
    常见Content-Type定义:
        普通文本:text/plain
        表单键值对:application/x-www-form-urlencoded
        文件数据:application/octet-stream
        json数据:application/json
        xml数据:text/xml

Android中常见编码Base64和URL编码

    URL编码:http协议中请求的url不支持中文和特殊字符(如&?),所以需要对url进行编码和解码,编码使用的是URLEncoder,解码使用的是URLDecoder;

    //进行url编码
    URLEncoder.encode(url)
    //进行url解码
    URLDecoder.decode(encodeUrl)

    Base64:可以将二进制数据对象转为字符串,主要用于在http传输中将一些比较大的比如二进制数据,编码为字符串,适合放入url进行传递,而且具有非明文行。应用场景如下:

        将文件进行base64编码为字符串后再上传,代码如下:

     
   private void base64Image() {
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(CompressFormat.PNG, 100, baos);

            byte[] encode = Base64.encode(baos.toByteArray(), Base64.DEFAULT);
            tv_result.setText(new String(encode));
        }

        将对象进行base64编码为字符串后,可以进行本地缓存,代码如下:

        private void base64Object() {
            Object obj = new Object();
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            ObjectOutputStream oo;
            try {
                oo = new ObjectOutputStream(bo);
                oo.writeObject(obj);
            } catch (IOException e) {
                e.printStackTrace();
            }

            byte[] encode = Base64.encode(bo.toByteArray(), Base64.DEFAULT);
            tv_result.setText(new String(encode));
        }

Android中的数字摘要,加密和解密 数字摘要:是指通过算法将长数据变为短数据,通常用来标识数据的唯一性,是否被修改,常用的加密算法有md5和sha1,如安卓app的签名也是用这2种算法计算的; md5由于具有不可逆性,也被用来作为密码加密,并且通常情况下为了让加密过程变的不可预测,我们会进行加盐操作,代码如下: /** * 使用md5方式进行加密 * @return */
private String md5(String password) {
    StringBuffer sb = new StringBuffer();
    try {
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(password.getBytes());
        byte[] digest = messageDigest.digest();
        for (int i = 0; i < digest.length; i++) {
            String str = Integer.toHexString(digest[i] & 0xff);

            if (str.length() == 1) {
                str = str + "0";
            }
            sb.append(str);

        }


    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return sb.toString();
}



sha1也不可逆,比md5长度更长,所以更安全,但是加密的效率比md5要慢一些,如文件的秒传功能,以及相同的v4包冲突都是根据文件的sha1值进行比对的。 /** * 使用sha-1方式进行加密 * @return */
 private String sha1(String password) {
        StringBuffer sb = new StringBuffer();
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
            messageDigest.update(password.getBytes());
            byte[] digest = messageDigest.digest();
            for (int i = 0; i < digest.length; i++) {
                String str = Integer.toHexString(digest[i] & 0xff);

                if (str.length() == 1) {
                    str = str + "0";
                }
                sb.append(str);

            }


        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }



加密和解密,一般分为对称加密和非对称加密
对称加密: 
密钥可以自己指定,只有一把密钥,如果密钥暴露,文件就会被暴露,
常见对称加密算法有DES算法(Data Encryption Standard)和AES算法(Advanced Encryption Standard),
特点是加密速度很快,但是缺点是安全性较低,因为只要密钥暴漏,数据就可以被解密了。 
非对称加密:有两把钥匙(密钥对),公钥和私钥,公钥的话给别人,私钥自己保存 
常见非对称加密算法是RSA
2把密钥通常是通过程序生成,不能自己指定
特点是加密速度慢些,但是安全系数很高
加密和解密的规则是:公钥加密只能私钥解密,私钥加密只能公钥解密
应用场景举例:在集成支付宝支付sdk时,需要生成私钥和公钥,公钥需要设置到支付宝网站的管理后台,在程序中调用支付接口的时候,使用我们自己的私钥进行加密,这样支付宝由于有公钥可以解密,其他人即时劫持了数据,但是没有公钥,也无法解密。
代码实践,使用hmAndroidUtils中的工具类进行操作
DES加密和解密的代码如下:
String data = "我是俊哥";
String desKey = "青龙偃月刀";// 密钥,口号
boolean isDesEncrypt = false;
private void useDes() {
    try {
        if(isDesEncrypt){
            //解密
            text.setText(Des.decrypt(text.getText().toString(), desKey));
        }else {
            //加密
            text.setText(Des.encrypt(data, desKey));
        }
        isDesEncrypt = !isDesEncrypt;

    } catch (Exception e) {
        e.printStackTrace();
    }
}
RSA加密和解密的代码如下:
//1.生成密钥对,设计口号
try {
    Map<String, Object> genKeyPair = RSACrypt.genKeyPair();
    //2.获取公钥
    publicKey = RSACrypt.getPublicKey(genKeyPair);
    //3.获取私钥
    privateKey = RSACrypt.getPrivateKey(genKeyPair);
} catch (Exception e) {
    e.printStackTrace();
}
private boolean isRSAEncrypt = false;
protected void useRSA() {
    try {
        if(isRSAEncrypt){
            //公钥解密
            String str = text.getText().toString();
            byte[] bs = RSACrypt.decryptByPublicKey(RSACrypt.decode(str), publicKey);
            text.setText(new String(bs));
        }else {
            //私钥加密
            byte[] bs = RSACrypt.encryptByPrivateKey(data.getBytes(), privateKey);
            text.setText(RSACrypt.encode(bs));
        }
        isRSAEncrypt = !isRSAEncrypt;
    } catch (Exception e) {
        e.printStackTrace();
    }
}











                
<think>好的,我现在需要解决用户的问题:如何在Python爬虫中对请求参数进行加密。用户提到了之前的回答相关引用,我需要结合这些信息来给出详细的步骤方法。 首先,回顾用户之前的对话,用户已经了解了如何添加GETPOST请求的参数,现在关注的是参数加密。根据提供的引用内容,加密通常涉及到逆向分析JavaScript代码,然后用Python模拟加密逻辑。引用1提到使用hashlib来模拟MD5加密,引用23讨论了逆向JS用Python重写加密函数,引用4提到了时间戳、参数排序Base64加密的例子。 用户的需求可能包括常见的加密方法,如哈希、Base64、AES等,以及如何处理动态参数如时间戳随机数。此外,用户可能还想了解如何逆向JS找到加密逻辑,这是实际爬虫中常遇到的难点。 接下来,我需要组织回答的结构。首先概述加密的必要性,然后分步骤介绍常见加密方法,包括哈希、Base64对称加密(如AES)、非对称加密(如RSA)。然后详细说明如何逆向分析JavaScript,包括使用浏览器开发者工具定位加密函数,调试并理解逻辑,最后用Python实现。可能需要结合引用中的例子,如MD5模拟、Base64处理,以及动态参数生成。 还要注意用户可能遇到的困难,比如复杂的JS混淆,这时可能需要工具如PyExecJS来执行JS代码,或者使用自动化工具如Selenium。同时,提醒用户注意法律道德规范,避免侵犯隐私或触犯法律。 最后,生成相关问题,帮助用户进一步学习,比如处理JS混淆、解决动态密钥、提升逆向效率等。 需要确保回答清晰,步骤明确,代码示例正确,并正确引用之前的资料,比如引用1MD5示例,引用4的Base64时间戳处理。同时,保持语言口语化,避免使用专业术语过多,但必要时解释清楚。</think>在Python爬虫中处理请求参数加密,需要通过逆向分析目标网站的加密逻辑,并采用Python代码模拟实现。以下是具体实现方法步骤: --- ### 一、常见加密类型及Python实现 #### 1. 哈希算法(如MD5/SHA) 用于参数签名验证,通过不可逆加密生成唯一标识 ```python import hashlib def md5_encrypt(text): md5 = hashlib.md5() md5.update(text.encode('utf-8')) return md5.hexdigest() # 示例:加密时间戳 timestamp = str(int(time.time()*1000)) sign = md5_encrypt(f"key={timestamp}&salt=abc123") ``` [^1] #### 2. Base64编码 常用于简单数据混淆处理 ```python import base64 # 参数编码 param = "page=2&size=20".encode('utf-8') encoded = base64.b64encode(param).decode() # 解码验证 decoded = base64.b64decode(encoded).decode() ``` [^4] #### 3. 对称加密(AES/DES) 需要获取密钥进行加解密 ```python from Crypto.Cipher import AES import binascii def aes_encrypt(data, key, iv): cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode()) padded = data + (16 - len(data) % 16) * chr(16 - len(data) % 16) encrypted = cipher.encrypt(padded.encode()) return binascii.b2a_hex(encrypted).decode() # 示例使用 encrypted = aes_encrypt('page=1', '1234567890123456', '1234567890123456') ``` #### 4. 非对称加密(RSA) 处理需要公钥加密的场景 ```python from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 def rsa_encrypt(data, public_key): rsa_key = RSA.importKey(public_key) cipher = PKCS1_v1_5.new(rsa_key) return base64.b64encode(cipher.encrypt(data.encode())).decode() ``` --- ### 二、逆向分析JS加密流程 #### 步骤1:定位加密入口 1. 使用Chrome开发者工具(F12) 2. 在Network面板捕获加密请求 3. 通过XHR断点或搜索加密参数定位JS文件 #### 步骤2:调试加密逻辑 ```javascript // 典型加密函数结构 function encryptParams(params) { let timestamp = Date.now(); let sorted = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join('&'); return md5(sorted + salt_key); } ``` #### 步骤3:Python复现逻辑 ```python import time def generate_params(page): params = { "page": page, "ts": int(time.time()*1000), "nonce": random.randint(1000,9999) } sorted_str = '&'.join([f"{k}={v}" for k,v in sorted(params.items())]) params['sign'] = hashlib.sha256(f"{sorted_str}appSecret").hexdigest() return params ``` [^4] --- ### 三、实战案例解析 以某电商网站搜索接口为例: 1. 原始请求参数: ```python {"keyword": "手机", "page": 1} ``` 2. 加密后参数: ```python { "payload": "eyJraWQiOiIxMjM0NSIsImVuY3J5cHRlZERhdGEiOiJNek...", "x-sign": "a1b2c3d4e5f6" } ``` 3. Python复现流程: ```python def encrypt_payload(params): # 步骤1:添加时间戳 params['timestamp'] = int(time.time()*1000) # 步骤2:参数排序并序列化 sorted_params = json.dumps(params, sort_keys=True) # 步骤3:AES加密 encrypted = aes_encrypt(sorted_params, AES_KEY, AES_IV) # 步骤4:生成签名 sign = md5_encrypt(encrypted + SIGN_SALT) return {"payload": encrypted, "x-sign": sign} ``` --- ### 四、特殊场景处理 1. **动态密钥**:通过首次请求获取加密密钥 2. **环境检测**:使用`execjs`库直接执行JS代码 ```python import execjs with open('encrypt.js') as f: js_code = f.read() ctx = execjs.compile(js_code) encrypted = ctx.call('encrypt', 'raw_data') ``` 3. **反调试绕过**:使用无头浏览器获取加密结果 ```python from selenium.webdriver import ChromeOptions options = ChromeOptions() options.add_argument('--headless') driver = webdriver.Chrome(options=options) driver.get(url) encrypted = driver.execute_script('return window.encrypt(param);') ``` --- ### 五、注意事项 1. 优先使用网站的公开API接口 2. 遵守robots.txt协议 3. 控制请求频率避免被封禁 4. 加密逻辑变更时需要及时更新代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安果移不动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值