1. 程式人生 > >android Java 中使用RSA加密爬坑記錄

android Java 中使用RSA加密爬坑記錄

1整體流程
後臺生成一個RSA祕鑰對,包括公鑰和私鑰
後臺將公鑰字串下發給客戶端,
然後客戶端用此公鑰生成一個RSAPublicKey物件,再將手機號密碼等資料用此物件加密,
客戶端將加密的資料傳送給後臺,
後臺將加密的資料用私鑰解密。
這裡寫圖片描述

由於後臺是PHP的,所以有一些問題時候不太好排查是哪裡的問題。下面說一下遇到的坑。
1 公私鑰格式
一般預設的公鑰格式是這樣的

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiwMSxbRias7DmFkp6V0Qx2nMG+"/n
AuhhR7H/wj62aufaDlUwhzaWQOKXHi
+SBVcTM0n+qzhtt4Kmr44MHAqW8NE9Pgzx UY8S7WVLn9wEGKGpZKlSHlZUdOKUabBFbS7dyBoVTYTkhrfXnOvtJJz5KGeYPT2x dEwA78dYEmHxvmwhrwIDAQAB -----END PUBLIC KEY-----

私鑰是這樣的

-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKLAxLFtGJqzsOYW
SnpXRDHacwYC6GFHsf/CPrZq59oOVTCHNpZA4pceL5IFVxMzSf6rOG23gqavjgwc
Cpbw0T0+DPFRjxLtZUuf3AQYoalkqVIeVlR04pRpsEVtLt3IGhVNhOSGt9ec6+0
k nPkoZ5g9PbF0TADvx1gSYfG+bCGvAgMBAAECgYAXWeceudNs5tk7ufkHopuzN2+H bkVfJ8U/N+R9kcsgOyw34T6QwlCAdCFJJyD+LT6xnmljPJAvUELmM+PFElpC34e5 cJUFGhwjDax18tb3LW7/MBB/XH1W+9KS5ninn3Homan1x8VIE9104QMLmj2HwDCH nI9HMXmYVhmzylNFIQJBANgvsTWq3Rw8UOXTY9uMR65Ia4Rz4fr0jyD9UIhF7j5+ dEycncrI9d7XjxgEObcegR8eoCGCALMzEmXyjcDbov8CQQDAuemo/OmHLqpA8tQm MHhvSdLxV0lruez3ok1gFuqwTtMxBsipLFVkTZMnMqnKY/ZDqFDrXOpom7yvEy5p BXFRAkAxDTEyMiCVRYI9g2dG619gRgJPPVPq8w5+t7tMEEHsYBjXQTn0RwCynUpU crD9wagefX5r2+l4v3/PLefH+I3VAkBvcpLmP+qjW57klAeOVfUvFde/7
CPvAcNA qEBqUpZAgjSqYyvieFqg+CMiRa/d89RS56BzmnWLLJP+Ae+Sl60hAkEAuhheSdjL vaVUq5UZPEtqZAuIRbQHETU7/INSViJeKvaSg9MuXJUG0f98HweMRLxHr1TjcX1c MGojP9s2ME7b3A== -----END PRIVATE KEY-----

可以看到都有一個頭部和尾部用來表示是公私鑰。
但是java中用收到的用於生成加密的物件接收的公鑰自串是要把頭和尾去掉的也就是這樣
去掉頭和尾

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiwMSxbRias7DmFkp6V0Qx2nMG+"/n
AuhhR7H/wj62aufaDlUwhzaWQOKXHi+SBVcTM0n+qzhtt4Kmr44MHAqW8NE9Pgzx
UY8S7WVLn9wEGKGpZKlSHlZUdOKUabBFbS7dyBoVTYTkhrfXnOvtJJz5KGeYPT2x
dEwA78dYEmHxvmwhrwIDAQAB

還要注意,如果字串不是後臺直接返回的,或者是直接將字串拷貝到變數的值中的時候,預設會加換行符,並且如果字串中出現”/”會加轉義換行符。所以要將字串中的所有\n和\去掉。
轉義換行等所有無關內容去掉

這裡寫圖片描述

2 Base64版本
這個問題不一定都會出現,因為在使用一些第三方的sdk時候,難免會引入各種Base64的版本。所以有可能會出現問題。
這裡寫圖片描述

我這裡最後用的是android自帶的版本是沒問題的。
這個包下的

android.util.Base64

3 Cipher建立的引數
用於加密時的Cipher,建立的引數不要寫成只帶”RSA”的

Cipher cipher = Cipher.getInstance("RSA");

應為這種的

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

4 最後不要忘了將引數用Base64編碼

 param = URLEncoder.encode((String)param,"utf-8");

因為如果少了這一步,將會出現加密的資料中的+號等符號是空格。

最後是執行成功的程式碼。以為客戶端只需要加密。所以只有加密的方法。

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;


/**
 * Author: yeliang([email protected])
 * Date: 2018/4/28
 * Time: 下午5:43
 * Description:
 */

public class RSAUtil {

    public static final String CHARSET = "UTF-8";
    public static final String RSA_ALGORITHM = "RSA";


    /**
     * 得到公鑰
     *
     * @param publicKey 金鑰字串(經過base64編碼)
     * @throws Exception
     */
    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通過X509編碼的Key指令獲得公鑰物件
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(android.util.Base64.decode(publicKey.getBytes(), android.util.Base64.DEFAULT));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }

    /**
     * 公鑰加密
     * @param data
     * @param publicKey
     * @return
     */
    public static String publicEncrypt(String data, RSAPublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return android.util.Base64.encodeToString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()), android.util.Base64.DEFAULT);
        } catch (Exception e) {
            throw new RuntimeException("加密字串[" + data + "]時遇到異常", e);
        }
    }



    private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
        int maxBlock = 0;
        if (opmode == Cipher.DECRYPT_MODE) {
            maxBlock = keySize / 8;
        } else {
            maxBlock = keySize / 8 - 11;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] buff;
        int i = 0;
        try {
            while (datas.length > offSet) {
                if (datas.length - offSet > maxBlock) {
                    buff = cipher.doFinal(datas, offSet, maxBlock);
                } else {
                    buff = cipher.doFinal(datas, offSet, datas.length - offSet);
                }
                out.write(buff, 0, buff.length);
                i++;
                offSet = i * maxBlock;
            }
        } catch (Exception e) {
            throw new RuntimeException("加解密閥值為[" + maxBlock + "]的資料時發生異常", e);
        }
        byte[] resultDatas = out.toByteArray();

        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultDatas;
    }

}

相關推薦

android Java 使用RSA加密記錄

1整體流程 後臺生成一個RSA祕鑰對,包括公鑰和私鑰 後臺將公鑰字串下發給客戶端, 然後客戶端用此公鑰生成一個RSAPublicKey物件,再將手機號密碼等資料用此物件加密, 客戶端將加密的資料傳送給後臺, 後臺將加密的資料用私鑰解密。 由於後臺

關於JAVARSA加簽解籤,私鑰加密公鑰解密和公鑰加密私鑰解密程式碼詳解

在專案中遇到的問題百度了許久總結出來的 私鑰加密公鑰解密和公鑰加密私鑰解密。 一般為了安全採用的是私鑰加密,公鑰解密(公鑰可以用Base64轉換後公開) package com.paic.ebank.creditcard.common.util; import java.s

記錄Android開發使用HorizontalScrollView的

前言 對於Android中的HorizontalScrollView控制元件,第一感覺是不怎麼熟悉的,在以往的專案開發基本沒有使用到. 橫向的滾動佈局也可以使用RecyclerView控制元件,所以HorizontalScrollView的使用頻率確實不高.

學習日記(1) 成功執行、編譯RN-android記錄

前言 從15年下半年開始,不斷的在網路上看見各路大神推薦React Native是如何神通廣大,但對於初識Android的我來說並不理解這到底是個什麼東西。最近團隊打算用這個技術實現我們客戶端App的首頁(會不定期釋出活動),這對於我來說又是一次自我的提升和

Javamd5加密

com char common span edi case codec mdt imp 方法一、 public final static String md5(String s) { char hexDigits[] = {‘0‘,‘1‘,‘2‘,‘

Java使用RSA加密算法對內容進行加密

hat trac ogg size gen cte false static doc 什麽是RSA加密算法 RSA是一種典型的非對稱性加密算法,具體介紹可參考阮一峰的日誌 RSA算法原理 下面是使用RSA算法對傳輸內容進行加密的一個簡要Java案例,主要用到了三個類,大體實

php和java加密和解密

padding 而不是 bsp enc openss 解密 div des算法 -c 遇到的java代碼如下: Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding"); 在php中使用des算法 始終校驗不

03、Swagger2和Springmvc整合詳細記錄記錄

component 效果 ges context tex ron 問題 package amp 時間 內容 備註 2018年6月18日 基本使用 spirngmvc整合swagger2 開始之前這個系列博文基本是,在項目的使用中一些模塊的內容記錄,但是

條理清晰的入門:使用Java實現RSA加密解密

條理清晰的入門:使用Java實現RSA加密解密 什麼是RSA 使用Java 需要匯入的標頭檔案 生成公鑰、私鑰 進行加密解密 金鑰的儲存 密文的儲存、讀取 什麼是RSA 翻一下以前的密碼

ElementUI 記錄

1. Form動態item校驗,資料繫結: model 只能為物件 prop的書寫規則:使用字串拼接,即 'model + prop' 所取得值要對應v-model中的資料(物件的點語法與陣列的index取值都是用 點 代替),舉例如下: <el-form v-if="

Android Studio3.2.1升級刨記錄

Android Studio出了3.2.1,我用的是2.3,所有決定升級一下,看看如何 為了保險一點,下載了官方的解壓版本,也就是說不含sdk,下載android-studio-ide-181.5014246-windows.zip 共999MB 解壓後直接執行,D:\android\android-st

量化交易(2)——OKEX簽名驗證MD5加密

hexdigest = hmac.new(payload, digestmod=hashlib.md5).hexdigest().upper() hexdigest = hashlib.md5(payload).hexdigest().upper()#OK支援的是這種

java學習筆記】踩記錄,異常:javax.el.PropertyNotFoundException: Property [XXX] not found on type [XXX.XXX.XXX.XXX]

練習JavaWeb專案時,報錯javax.el.PropertyNotFoundException,原因是EL表示式裡面的屬性和pojo裡面的屬性名字沒有對上,範了個低階錯誤。 jsp中: <li>歡迎您,${loginUser.username}!</li> pojo

Mybatis記錄

從程式執行流程分析: 1、解析mybatis配置檔案,生成抽象dom樹 2、逐個解析dom節點,生成對應的Java物件,儲存到Configuration類中 3、遇到子節點包含其他的配置檔案,遞迴解析 4、從資料來源中獲取session 從設計策略角度分析:   &nb

golangRSA加密與解密演算法

package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "fmt" ) // 可通過openssl產生

Java使用組合slf4j+log4j記錄日誌

log4j是一個具體的日誌系統,使用之前,在pom檔案中引入 <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <g

JAVADES加密方式示例

本問只簡要講解在JAVA中如何使用幾種加密的程式碼示例,關於加密演算法和數學知識不在本文討論範圍。 package com.util; import java.security.NoSuchAlgorithmException; import java.secu

android studio 3.1.3之旅

出錯資訊:The SourceSet 'instrumentTest' is not recognized by the Android Gradle Plugin. Perhaps you misspelled something? 翻譯:“SourceSet” 的

vue-記錄(一)

一.編譯的時候提示找不到HeadNav.vue模組 ERROR Failed to compile with 1 errors 23:44:15This relative module was not found: * ./components/HeadNav in ./node_modules/cac

【轉載】【記錄】hyperledger caliper 效能測試工具使用的一些問題記錄

原文: https://blog.csdn.net/raogeeg/article/details/82752613 安裝方法詳見:https://github.com/hyperledger/caliper hyperledger caliper 使用過程的一些坑以及解決辦法 not ok 2 Fai