亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android使用RSA加密實(shí)現(xiàn)接口調(diào)用時的校驗功能

 更新時間:2020年12月23日 15:24:03   作者:霸道的程序猿  
這篇文章主要介紹了Android+Java使用RSA加密實(shí)現(xiàn)接口調(diào)用時的校驗功能,幫助大家更好的利用Android進(jìn)行開發(fā),感興趣的朋友可以了解下

RSA算法是一種非對稱加密算法,那么何為非對稱加密算法呢?

一般我們理解上的加密是這樣子進(jìn)行的:原文經(jīng)過了一把鑰匙(密鑰)加密后變成了密文,然后將密文傳遞給接收方,接收方再用這把鑰匙(密鑰)解開密文。在這個過程中,其實(shí)加密和解密使用的是同一把鑰匙,這種加密方式稱為對稱加密。

而非對稱加密就是和對稱加密相對,加密用的鑰匙和解密所用的鑰匙,并不是同一把鑰匙。非對稱加密首先會創(chuàng)建兩把鑰匙,而這兩把鑰匙是成對的分別稱為公鑰和私鑰。在進(jìn)行加密時我們使用公鑰進(jìn)行加密,而在解密的時候就必須要使用私鑰才能進(jìn)行解密,這就是非對稱加密算法。

假如使用非對稱加密,甲發(fā)送消息給乙,這時候乙會預(yù)先創(chuàng)建好兩把鑰匙,私鑰乙自己保存好,然后把公鑰發(fā)送給甲,甲使用公鑰對信息進(jìn)行加密,然后傳給乙。最后乙使用自己的私鑰對數(shù)據(jù)進(jìn)行解密。這個過程中,公鑰還是有可能被第三者所截獲,但是不同的是,這個第三者縱然得到了公鑰,也無法解開密文,因為解密密文所需要的私鑰從始至終一直在乙的手里。因此這個過程是安全的。

在一個Android應(yīng)用中錄音完成后將錄音文件上傳到SpringBoot搭建的后臺接口中。

由于Android應(yīng)用中沒有登錄功能,所以需要對一串自定義字符串進(jìn)行加密并傳輸,然后在SpringBoot后臺進(jìn)行解密驗證。防止上傳接口暴露。

實(shí)現(xiàn)

首先在SpringBoot端新建一個RsaUtils工具類

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;

//java 后端
public class RsaUtils {
 //私鑰
 public static String privateKey = "自己生成的私鑰";
 //公鑰
 private static String publicKey = "自己生成的公鑰";
 /**
  * RSA最大加密明文大小
  */
 private static final int MAX_ENCRYPT_BLOCK = 117;

 /**
  * RSA最大解密密文大小
  */
 private static final int MAX_DECRYPT_BLOCK = 128;

 /**
  * 獲取密鑰對
  *
  * @return 密鑰對
  */
 public static KeyPair getKeyPair() throws Exception {
  KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
  generator.initialize(1024);
  return generator.generateKeyPair();
 }

 /**
  * 獲取私鑰
  *
  * @param privateKey 私鑰字符串
  * @return
  */
 public static PrivateKey getPrivateKey(String privateKey) throws Exception {
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");

  byte[] decodedKey = com.sun.org.apache.xerces.internal.impl.dv.util.Base64.decode(new String(privateKey.getBytes()));
  PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
  return keyFactory.generatePrivate(keySpec);
 }

 /**
  * 獲取公鑰
  *
  * @param publicKey 公鑰字符串
  * @return
  */
 public static PublicKey getPublicKey(String publicKey) throws Exception {
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  byte[] decodedKey = Base64.decode(publicKey);
  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
  return keyFactory.generatePublic(keySpec);
 }

 /**
  * RSA加密
  *
  * @param data  待加密數(shù)據(jù)
  * @param publicKey 公鑰
  * @return
  */
 public static String encrypt(String data, PublicKey publicKey) throws Exception {
  Cipher cipher = Cipher.getInstance("RSA");
  cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  int inputLen = data.getBytes().length;
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  int offset = 0;
  byte[] cache;
  int i = 0;
  // 對數(shù)據(jù)分段加密
  while (inputLen - offset > 0) {
   if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
    cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
   } else {
    cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
   }
   out.write(cache, 0, cache.length);
   i++;
   offset = i * MAX_ENCRYPT_BLOCK;
  }
  byte[] encryptedData = out.toByteArray();
  out.close();
  // 獲取加密內(nèi)容使用base64進(jìn)行編碼,并以UTF-8為標(biāo)準(zhǔn)轉(zhuǎn)化成字符串
  // 加密后的字符串
  return new String(Base64.encode((encryptedData)));
 }

 /**
  * RSA解密
  *
  * @param data  待解密數(shù)據(jù)
  * @param privateKey 私鑰
  * @return
  */
 public static String decrypt(String data, PrivateKey privateKey) throws Exception {

  Cipher cipher = Cipher.getInstance("RSA");
  cipher.init(Cipher.DECRYPT_MODE, privateKey);
  byte[] dataBytes = Base64.decode(data);
  int inputLen = dataBytes.length;
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  int offset = 0;
  byte[] cache;
  int i = 0;
  // 對數(shù)據(jù)分段解密
  while (inputLen - offset > 0) {
   if (inputLen - offset > MAX_DECRYPT_BLOCK) {
    cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
   } else {
    cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
   }
   out.write(cache, 0, cache.length);
   i++;
   offset = i * MAX_DECRYPT_BLOCK;
  }
  byte[] decryptedData = out.toByteArray();
  out.close();
  // 解密后的內(nèi)容
  return new String(decryptedData, "UTF-8");
 }

 /**
  * 簽名
  *
  * @param data  待簽名數(shù)據(jù)
  * @param privateKey 私鑰
  * @return 簽名
  */
 public static String sign(String data, PrivateKey privateKey) throws Exception {
  byte[] keyBytes = privateKey.getEncoded();
  PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  PrivateKey key = keyFactory.generatePrivate(keySpec);
  Signature signature = Signature.getInstance("MD5withRSA");
  signature.initSign(key);
  signature.update(data.getBytes());
  return Base64.encode(signature.sign());
 }

 /**
  * 驗簽
  *
  * @param srcData 原始字符串
  * @param publicKey 公鑰
  * @param sign  簽名
  * @return 是否驗簽通過
  */
 public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {
  byte[] keyBytes = publicKey.getEncoded();
  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  PublicKey key = keyFactory.generatePublic(keySpec);
  Signature signature = Signature.getInstance("MD5withRSA");
  signature.initVerify(key);
  signature.update(srcData.getBytes());
  return signature.verify(Base64.decode(sign));
 }


/* public static void main(String[] args) {
  try {
   // 生成密鑰對
   KeyPair keyPair = getKeyPair();
   String privateKey = new String(Base64.getEncoder().encode(keyPair.getPrivate().getEncoded()));
   String publicKey = new String(Base64.getEncoder().encode(keyPair.getPublic().getEncoded()));
   System.out.println("私鑰:" + privateKey);
   System.out.println("公鑰:" + publicKey);


   // RSA加密
*//*   String data = "待加密的文字內(nèi)容";
   String encryptData = encrypt(data, getPublicKey(publicKey));
   System.out.println("加密后內(nèi)容:" + encryptData);
   // RSA解密
   String decryptData = decrypt("encryptData ", getPrivateKey(privateKey));
   System.out.println("解密后內(nèi)容:" + decryptData);

   // RSA簽名
   String sign = sign(data, getPrivateKey(privateKey));
   // RSA驗簽
   boolean result = verify(data, getPublicKey(publicKey), sign);
   System.out.print("驗簽結(jié)果:" + result);*//*
  } catch (Exception e) {
   e.printStackTrace();
   System.out.print("加解密異常");
  }
 }*/

}

然后運(yùn)行此工具類的main方法中的生成密鑰對的方法,獲取到生成的公鑰和密鑰對。

然后將它們賦值到最上面的privateKey和publicKey。

然后在Android端中也新建一個工具類RsaUtils

package com.badao.badaoimclient.common;

import android.util.Base64;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;

public class RsaUtils{

 //公鑰
 public static String publicKey="跟Java端同樣的公鑰";
 /**
  * RSA最大加密明文大小
  */
 private static final int MAX_ENCRYPT_BLOCK = 117;

 /**
  * RSA最大解密密文大小
  */
 private static final int MAX_DECRYPT_BLOCK = 128;

 

 /**
  * 獲取公鑰
  *
  * @param publicKey 公鑰字符串
  * @return
  */
 public static PublicKey getPublicKey(String publicKey) throws Exception {
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  byte[] decodedKey =Base64.decode(publicKey.getBytes(), Base64.DEFAULT);
  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
  return keyFactory.generatePublic(keySpec);
 }

 /**
  * RSA加密
  *
  * @param data 待加密數(shù)據(jù)
  * @param publicKey 公鑰
  * @return
  */
 public static String encrypt(String data, PublicKey publicKey) throws Exception {
  Cipher cipher ;
  cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding");
  cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  int inputLen = data.getBytes().length;
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  int offset = 0;
  byte[] cache;
  int i = 0;
  // 對數(shù)據(jù)分段加密
  while (inputLen - offset > 0) {
   if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
    cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);
   } else {
    cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);
   }
   out.write(cache, 0, cache.length);
   i++;
   offset = i * MAX_ENCRYPT_BLOCK;
  }
  byte[] encryptedData = out.toByteArray();
  out.close();
  // 獲取加密內(nèi)容使用base64進(jìn)行編碼,并以UTF-8為標(biāo)準(zhǔn)轉(zhuǎn)化成字符串
  // 加密后的字符串
  return new String(Base64.encode(encryptedData, Base64.DEFAULT));
 }

}

這里的公鑰與上面生成的公鑰一致。

注意著兩個工具類的區(qū)別

在Android工具類中的Base64引入的是

import android.util.Base64;

而在Java中引入的Base64是

import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

注意這里為什么不是引用java.util.Base64,因為會有換行導(dǎo)致的轉(zhuǎn)移字符的問題。

然后在Android中對字符串進(jìn)行加密

//獲取加密字符串
String escode = "";
try {
  escode = RsaUtils.encrypt(key,RsaUtils.getPublicKey(RsaUtils.publicKey));
 } catch (Exception e) {
  e.printStackTrace();
}

將其作為接口調(diào)用的參數(shù)傳遞到Java中進(jìn)行解密

if(decode.equals(RsaUtils.decrypt(key,RsaUtils.getPrivateKey(RsaUtils.privateKey))))
  {
   try
   {
    // 上傳文件路徑
    String filePath = RuoYiConfig.getUploadPath();
    // 上傳并返回新文件名稱
    String fileName = FileUploadUtils.upload(filePath, file);
    String url = serverConfig.getUrl() + fileName;
    AjaxResult ajax = AjaxResult.success();
    ajax.put("fileName", fileName);
    ajax.put("url", url);
    return ajax;
   }
   catch (Exception e)
   {
    return AjaxResult.error(e.getMessage());
   }
  }else {
   return AjaxResult.error("非法訪問");
  }

這樣就限制了只能通過指定的移動端對文件上傳接口進(jìn)行訪問。

在移動端調(diào)用接口進(jìn)行測試

可見調(diào)用接口前加密成功

并且能用過后臺接口的解密校驗

這樣別的第三方請求接口就沒法請求

以上就是Android使用RSA加密實(shí)現(xiàn)接口調(diào)用時的校驗功能的詳細(xì)內(nèi)容,更多關(guān)于Android rsa加密接口調(diào)用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • android 限制某個操作每天只能操作指定的次數(shù)(示例代碼詳解)

    android 限制某個操作每天只能操作指定的次數(shù)(示例代碼詳解)

    這篇文章主要介紹了android 限制某個操作每天只能操作指定的次數(shù),本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Android最新版本開發(fā)環(huán)境搭建圖文教程

    Android最新版本開發(fā)環(huán)境搭建圖文教程

    這篇文章主要為大家詳細(xì)介紹了Android最新版本開發(fā)環(huán)境搭建圖文教程,重點(diǎn)在于配置JDK,以及adt-bundle,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Android實(shí)現(xiàn)簡單QQ登錄頁面

    Android實(shí)現(xiàn)簡單QQ登錄頁面

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)簡單QQ登錄頁面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android nativePollOnce函數(shù)解析

    Android nativePollOnce函數(shù)解析

    這篇文章主要介紹了Android nativePollOnce函數(shù)解析的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下
    2021-03-03
  • 深入淺析Android坐標(biāo)系統(tǒng)

    深入淺析Android坐標(biāo)系統(tǒng)

    這篇文章主要介紹了 深入淺析Android坐標(biāo)系統(tǒng)的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • Android應(yīng)用關(guān)閉的情況以及識別方法詳解

    Android應(yīng)用關(guān)閉的情況以及識別方法詳解

    對于現(xiàn)在的安卓手機(jī)而言,很多功能都是在逐步完善的,這篇文章主要給大家介紹了關(guān)于Android應(yīng)用關(guān)閉的情況以及識別的相關(guān)資料,文章通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • android實(shí)現(xiàn)簡單音樂播放器

    android實(shí)現(xiàn)簡單音樂播放器

    這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)簡單音樂播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 深入理解Android 5.0中的Toolbar

    深入理解Android 5.0中的Toolbar

    相信大家都有所體會,搜索Toolbar相關(guān)文章滿天飛,但是大都不是很全面,每次要用到的時候又要重頭過濾一遍。而且隨著版本升級很多較早的文章的方法已經(jīng)失效,最近剛好好用到Toolbar,就將相關(guān)配置整理下,方便以后需要的時候或者有需要的朋友們參考學(xué)習(xí)。
    2017-01-01
  • Android開發(fā)教程之Fragment定義、創(chuàng)建與使用方法詳解【包含Activity通訊,事務(wù)執(zhí)行等】

    Android開發(fā)教程之Fragment定義、創(chuàng)建與使用方法詳解【包含Activity通訊,事務(wù)執(zhí)行等】

    這篇文章主要介紹了Android開發(fā)教程之Fragment定義、創(chuàng)建與使用方法,詳細(xì)介紹了Fragment的概念、功能、定義、創(chuàng)建及使用方法,包括Fragment與Activity通訊,Fragment事務(wù)執(zhí)行及Fragment應(yīng)用示例等,需要的朋友可以參考下
    2017-11-11
  • android動態(tài)設(shè)置app當(dāng)前運(yùn)行語言的方法

    android動態(tài)設(shè)置app當(dāng)前運(yùn)行語言的方法

    下面小編就為大家?guī)硪黄猘ndroid動態(tài)設(shè)置app當(dāng)前運(yùn)行語言的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03

最新評論