frida hook AES DES RSA 自吐算法
大家好,我是王鐵頭 一個乙方安全公司搬磚的菜雞 今天分享的是frida hook AES DES RSA 自吐算法
持續更新移動安全,iot安全,編譯原理相關原創視頻文章
視頻演示:https://space.bilibili.com/430241559
在分析通信協議的時候 經常遇到的加密算法就是那幾個
- AES
- DES
- 3DES
- RSA
在hook AES DES RSA這些常見的加密算法之前
這里先看一下3個算法的java實現
1 AES加解密 java代碼實現
1.1 AES加密
//bytesContent 要加密的數據
//key 密鑰
public static byte[] aes_enc(byte[] bytesContent, String key) throws Exception
{
//key相關
byte[] raw = key.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
//"算法/模式/補碼方式" 初始化cipher
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
//執行加密
byte[] enc = cipher.doFinal(bytesContent);
return enc;
}
1.2 AES解密
//bytesContent 要解密的數據
//key 密鑰
public byte[] aes_dec(byte[] bytesContent, String key) throws Exception
{
//key相關
byte[] raw = key.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
//"算法/模式/補碼方式" 初始化cipher
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
//執行解密
byte[] dec = cipher.doFinal(bytesContent);
return dec;
}
這里AES加解密的區別只有一點
//Cipher.DECRYPT_MODE為解密
//Cipher.ENCRYPT_MODE 加密
cipher.init(Cipher.DECRYPT_MODE, skeySpec)
2. DES加解密 java實現代碼
2.1 DES加密
private static byte[] des_enc(byte[] data, byte[] key) throws Exception {
// 生成一個可信任的隨機數源
SecureRandom sr = new SecureRandom();
// 從原始密鑰數據創建DESKeySpec對象
DESKeySpec dks = new DESKeySpec(key);
// 創建一個密鑰工廠,然后用它把DESKeySpec轉換成SecretKey對象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher對象實際完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密鑰初始化Cipher對象
cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
return cipher.doFinal(data);
}
2.2 DES解密
private static byte[] des_dec(byte[] data, byte[] key) throws Exception {
// 生成一個可信任的隨機數源
SecureRandom sr = new SecureRandom();
// 從原始密鑰數據創建DESKeySpec對象
DESKeySpec dks = new DESKeySpec(key);
// 創建一個密鑰工廠,然后用它把DESKeySpec轉換成SecretKey對象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher對象實際完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密鑰初始化Cipher對象
cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
return cipher.doFinal(data);
}
這里DES加解密的區別只有一點
//Cipher.DECRYPT_MODE為解密
//Cipher.ENCRYPT_MODE 加密
cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
3. RSA加解密 java代碼實現
RSA加解密代碼實現
public static void RSA(byte[] bytesData) throws Exception
{
//秘鑰長度為1024 生成秘鑰對
KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair= keyPairGenerator.generateKeyPair();
//獲取公鑰 私鑰
PublicKey publicKey=keyPair.getPublic();
PrivateKey privateKey=keyPair.getPrivate();
//公鑰加密 java默認"RSA"="RSA/ECB/PKCS1Padding"
Cipher cipher=Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encBytes = cipher.doFinal(bytesData);
//私鑰解密 java默認"RSA"="RSA/ECB/PKCS1Padding"
Cipher cipher1=Cipher.getInstance("RSA");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decBytes = cipher1.doFinal(encBytes);
Log.d("xxx",new String(decBytes));
}
這里忽略前面RSA加解密都需要的生成公鑰私鑰的部分
核心功能代碼如下
3.1 RSA加密代碼
//公鑰加密 java默認"RSA"="RSA/ECB/PKCS1Padding"
Cipher cipher=Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encBytes = cipher.doFinal(bytesData);
3.2 RSA解密代碼
//私鑰解密 java默認"RSA"="RSA/ECB/PKCS1Padding"
Cipher cipher1=Cipher.getInstance("RSA");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decBytes = cipher1.doFinal(encBytes);
這里RSA加解密的區別也只有一點
//Cipher.DECRYPT_MODE為解密 publicKey 公鑰加密
//Cipher.ENCRYPT_MODE為加密 privateKey 私鑰解密
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
看了上面的一些代碼 這里可以找到一些共性
雖然實現處有些區別 但大體架構和使用的java接口是可以找到一些規律的
這里出鏡率比較高的有
- secretKeySpec
- Cipher.getInstance
- cipher.init
- cipher.doFinal
- DESKeySpec
...(后續還有 這里不一一列舉)
查閱java幫助文檔可以發現, 這些API都是一些加密算法常用的接口, 那么實現自吐 就是hook加密算法常用的API,打印相關參數,以便於快速的定位算法和相關參數 加密模式等
在網上查找 相關資料 我找到了一份frida自吐算法的源碼 鏈接如下
https://blog.csdn.net/weixin_34365417/article/details/93088342
看了上面的源碼 作者寫的還是不錯的 而且不僅hook了 我上面提到的加密算法 還hook了一些消息摘要算法 MAC家族和md家族等 也就是 md5 sha 等通信協議中常用的hash算法 另外也有對 IV這種加密中用到的向量成員的hook
這里 我修改了下源碼
修改的部分主要分為下面幾點
- 針對上面的打印堆棧的代碼做了修改 修復在高版本 打印堆棧不換行的問題
- 增加了一些hook api
- 把原來的 python腳本換成了js
- 修復一個bug
- ui調整 增加顯示 加密模式 解密模式 把原腳本的dec結果 改成str結果 增加dofinal str顯示
4 修改后的源碼
var N_ENCRYPT_MODE = 1
var N_DECRYPT_MODE = 2
function showStacks() {
var Exception = Java.use("java.lang.Exception");
var ins = Exception.$new("Exception");
var straces = ins.getStackTrace();
if (undefined == straces || null == straces) {
return;
}
console.log("============================= Stack strat=======================");
console.log("");
for (var i = 0; i < straces.length; i++) {
var str = " " + straces[i].toString();
console.log(str);
}
console.log("");
console.log("============================= Stack end=======================\r\n");
Exception.$dispose();
}
//工具相關函數
var base64EncodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
base64DecodeChars = new Array((-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), (-1), 62, (-1), (-1), (-1), 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, (-1), (-1), (-1), (-1), (-1), (-1), (-1), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, (-1), (-1), (-1), (-1), (-1), (-1), 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, (-1), (-1), (-1), (-1), (-1));
function stringToBase64(e) {
var r, a, c, h, o, t;
for (c = e.length, a = 0, r = ''; a < c;) {
if (h = 255 & e.charCodeAt(a++), a == c) {
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4),
r += '==';
break
}
if (o = e.charCodeAt(a++), a == c) {
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
r += base64EncodeChars.charAt((15 & o) << 2),
r += '=';
break
}
t = e.charCodeAt(a++),
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6),
r += base64EncodeChars.charAt(63 & t)
}
return r
}
function base64ToString(e) {
var r, a, c, h, o, t, d;
for (t = e.length, o = 0, d = ''; o < t;) {
do
r = base64DecodeChars[255 & e.charCodeAt(o++)];
while (o < t && r == -1);
if (r == -1)
break;
do
a = base64DecodeChars[255 & e.charCodeAt(o++)];
while (o < t && a == -1);
if (a == -1)
break;
d += String.fromCharCode(r << 2 | (48 & a) >> 4);
do {
if (c = 255 & e.charCodeAt(o++), 61 == c)
return d;
c = base64DecodeChars[c]
} while (o < t && c == -1);
if (c == -1)
break;
d += String.fromCharCode((15 & a) << 4 | (60 & c) >> 2);
do {
if (h = 255 & e.charCodeAt(o++), 61 == h)
return d;
h = base64DecodeChars[h]
} while (o < t && h == -1);
if (h == -1)
break;
d += String.fromCharCode((3 & c) << 6 | h)
}
return d
}
function hexToBase64(str) {
return base64Encode(String.fromCharCode.apply(null, str.replace(/\r|\n/g, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")));
}
function base64ToHex(str) {
for (var i = 0, bin = base64Decode(str.replace(/[ \r\n]+$/, "")), hex = []; i < bin.length; ++i) {
var tmp = bin.charCodeAt(i).toString(16);
if (tmp.length === 1)
tmp = "0" + tmp;
hex[hex.length] = tmp;
}
return hex.join("");
}
function hexToBytes(str) {
var pos = 0;
var len = str.length;
if (len % 2 != 0) {
return null;
}
len /= 2;
var hexA = new Array();
for (var i = 0; i < len; i++) {
var s = str.substr(pos, 2);
var v = parseInt(s, 16);
hexA.push(v);
pos += 2;
}
return hexA;
}
function bytesToHex(arr) {
var str = '';
var k, j;
for (var i = 0; i < arr.length; i++) {
k = arr[i];
j = k;
if (k < 0) {
j = k + 256;
}
if (j < 16) {
str += "0";
}
str += j.toString(16);
}
return str;
}
function stringToHex(str) {
var val = "";
for (var i = 0; i < str.length; i++) {
if (val == "")
val = str.charCodeAt(i).toString(16);
else
val += str.charCodeAt(i).toString(16);
}
return val
}
function stringToBytes(str) {
var ch, st, re = [];
for (var i = 0; i < str.length; i++) {
ch = str.charCodeAt(i);
st = [];
do {
st.push(ch & 0xFF);
ch = ch >> 8;
}
while (ch);
re = re.concat(st.reverse());
}
return re;
}
//將byte[]轉成String的方法
function bytesToString(arr) {
var str = '';
arr = new Uint8Array(arr);
for (var i in arr) {
str += String.fromCharCode(arr[i]);
}
return str;
}
function bytesToBase64(e) {
var r, a, c, h, o, t;
for (c = e.length, a = 0, r = ''; a < c;) {
if (h = 255 & e[a++], a == c) {
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4),
r += '==';
break
}
if (o = e[a++], a == c) {
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
r += base64EncodeChars.charAt((15 & o) << 2),
r += '=';
break
}
t = e[a++],
r += base64EncodeChars.charAt(h >> 2),
r += base64EncodeChars.charAt((3 & h) << 4 | (240 & o) >> 4),
r += base64EncodeChars.charAt((15 & o) << 2 | (192 & t) >> 6),
r += base64EncodeChars.charAt(63 & t)
}
return r
}
function base64ToBytes(e) {
var r, a, c, h, o, t, d;
for (t = e.length, o = 0, d = []; o < t;) {
do
r = base64DecodeChars[255 & e.charCodeAt(o++)];
while (o < t && r == -1);
if (r == -1)
break;
do
a = base64DecodeChars[255 & e.charCodeAt(o++)];
while (o < t && a == -1);
if (a == -1)
break;
d.push(r << 2 | (48 & a) >> 4);
do {
if (c = 255 & e.charCodeAt(o++), 61 == c)
return d;
c = base64DecodeChars[c]
} while (o < t && c == -1);
if (c == -1)
break;
d.push((15 & a) << 4 | (60 & c) >> 2);
do {
if (h = 255 & e.charCodeAt(o++), 61 == h)
return d;
h = base64DecodeChars[h]
} while (o < t && h == -1);
if (h == -1)
break;
d.push((3 & c) << 6 | h)
}
return d
}
//stringToBase64 stringToHex stringToBytes
//base64ToString base64ToHex base64ToBytes
// hexToBase64 hexToBytes
// bytesToBase64 bytesToHex bytesToString
Java.perform(function () {
var secretKeySpec = Java.use('javax.crypto.spec.SecretKeySpec');
secretKeySpec.$init.overload('[B', 'java.lang.String').implementation = function (a, b) {
showStacks();
var result = this.$init(a, b);
console.log("======================================");
console.log("算法名:" + b + "|str密鑰:" + bytesToString(a));
console.log("算法名:" + b + "|Hex密鑰:" + bytesToHex(a));
return result;
}
var DESKeySpec = Java.use('javax.crypto.spec.DESKeySpec');
DESKeySpec.$init.overload('[B').implementation = function (a) {
showStacks();
var result = this.$init(a);
console.log("======================================");
var bytes_key_des = this.getKey();
console.log("des密鑰 |str " + bytesToString(bytes_key_des));
console.log("des密鑰 |hex " + bytesToHex(bytes_key_des));
return result;
}
DESKeySpec.$init.overload('[B', 'int').implementation = function (a, b) {
showStacks();
var result = this.$init(a, b);
console.log("======================================");
var bytes_key_des = this.getKey();
console.log("des密鑰 |str " + bytesToString(bytes_key_des));
console.log("des密鑰 |hex " + bytesToHex(bytes_key_des));
return result;
}
var mac = Java.use('javax.crypto.Mac');
mac.getInstance.overload('java.lang.String').implementation = function (a) {
showStacks();
var result = this.getInstance(a);
console.log("======================================");
console.log("算法名:" + a);
return result;
}
mac.update.overload('[B').implementation = function (a) {
//showStacks();
this.update(a);
console.log("======================================");
console.log("update:" + bytesToString(a))
}
mac.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
//showStacks();
this.update(a, b, c)
console.log("======================================");
console.log("update:" + bytesToString(a) + "|" + b + "|" + c);
}
mac.doFinal.overload().implementation = function () {
//showStacks();
var result = this.doFinal();
console.log("======================================");
console.log("doFinal結果: |str :" + bytesToString(result));
console.log("doFinal結果: |hex :" + bytesToHex(result));
console.log("doFinal結果: |base64 :" + bytesToBase64(result));
return result;
}
mac.doFinal.overload('[B').implementation = function (a) {
//showStacks();
var result = this.doFinal(a);
console.log("======================================");
console.log("doFinal參數: |str :" + bytesToString(a));
console.log("doFinal參數: |hex :" + bytesToHex(a));
console.log("doFinal結果: |str :" + bytesToString(result));
console.log("doFinal結果: |hex :" + bytesToHex(result));
console.log("doFinal結果: |base64 :" + bytesToBase64(result));
return result;
}
var md = Java.use('java.security.MessageDigest');
md.getInstance.overload('java.lang.String', 'java.lang.String').implementation = function (a, b) {
//showStacks();
console.log("======================================");
console.log("算法名:" + a);
return this.getInstance(a, b);
}
md.getInstance.overload('java.lang.String').implementation = function (a) {
//showStacks();
console.log("======================================");
console.log("算法名:" + a);
return this.getInstance(a);
}
md.update.overload('[B').implementation = function (a) {
//showStacks();
console.log("======================================");
console.log("update:" + bytesToString(a))
return this.update(a);
}
md.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
//showStacks();
console.log("======================================");
console.log("update:" + bytesToString(a) + "|" + b + "|" + c);
return this.update(a, b, c);
}
md.digest.overload().implementation = function () {
//showStacks();
console.log("======================================");
var result = this.digest();
console.log("digest結果 |hex:" + bytesToHex(result));
console.log("digest結果 |base64:" + bytesToBase64(result));
return result;
}
md.digest.overload('[B').implementation = function (a) {
//showStacks();
console.log("======================================");
console.log("digest參數 |str:" + bytesToString(a));
console.log("digest參數 |hex:" + bytesToHex(a));
var result = this.digest(a);
console.log("digest結果: |hex" + bytesToHex(result));
console.log("digest結果: |base64" + bytesToBase64(result));
return result;
}
var ivParameterSpec = Java.use('javax.crypto.spec.IvParameterSpec');
ivParameterSpec.$init.overload('[B').implementation = function (a) {
//showStacks();
var result = this.$init(a);
console.log("======================================");
console.log("iv向量: |str:" + bytesToString(a));
console.log("iv向量: |hex:" + bytesToHex(a));
return result;
}
var cipher = Java.use('javax.crypto.Cipher');
cipher.getInstance.overload('java.lang.String').implementation = function (a) {
//showStacks();
var result = this.getInstance(a);
console.log("======================================");
console.log("模式填充:" + a);
return result;
}
cipher.init.overload('int', 'java.security.Key').implementation = function (a, b) {
//showStacks();
var result = this.init(a, b);
console.log("======================================");
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密鑰:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密鑰:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.cert.Certificate').implementation = function (a, b) {
//showStacks();
var result = this.init(a, b);
console.log("======================================");
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function (a, b, c) {
//showStacks();
var result = this.init(a, b, c);
console.log("======================================");
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密鑰:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密鑰:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.cert.Certificate', 'java.security.SecureRandom').implementation = function (a, b, c) {
//showStacks();
var result = this.init(a, b, c);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.SecureRandom').implementation = function (a, b, c) {
//showStacks();
var result = this.init(a, b, c);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密鑰:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密鑰:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters').implementation = function (a, b, c) {
//showStacks();
var result = this.init(a, b, c);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密鑰:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密鑰:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.AlgorithmParameters', 'java.security.SecureRandom').implementation = function (a, b, c, d) {
//showStacks();
var result = this.init(a, b, c, d);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密鑰:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密鑰:" + bytesToHex(bytes_key));
return result;
}
cipher.init.overload('int', 'java.security.Key', 'java.security.spec.AlgorithmParameterSpec', 'java.security.SecureRandom').implementation = function (a, b, c, d) {
//showStacks();
var result = this.init(a, b, c, d);
if (N_ENCRYPT_MODE == a)
{
console.log("init | 加密模式");
}
else if(N_DECRYPT_MODE == a)
{
console.log("init | 解密模式");
}
var bytes_key = b.getEncoded();
console.log("init key:" + "|str密鑰:" + bytesToString(bytes_key));
console.log("init key:" + "|Hex密鑰:" + bytesToHex(bytes_key));
return result;
}
cipher.update.overload('[B').implementation = function (a) {
//showStacks();
var result = this.update(a);
console.log("======================================");
console.log("update:" + bytesToString(a));
return result;
}
cipher.update.overload('[B', 'int', 'int').implementation = function (a, b, c) {
//showStacks();
var result = this.update(a, b, c);
console.log("======================================");
console.log("update:" + bytesToString(a) + "|" + b + "|" + c);
return result;
}
cipher.doFinal.overload().implementation = function () {
//showStacks();
var result = this.doFinal();
console.log("======================================");
console.log("doFinal結果: |str :" + bytesToString(result));
console.log("doFinal結果: |hex :" + bytesToHex(result));
console.log("doFinal結果: |base64 :" + bytesToBase64(result));
return result;
}
cipher.doFinal.overload('[B').implementation = function (a) {
//showStacks();
var result = this.doFinal(a);
console.log("======================================");
console.log("doFinal參數: |str :" + bytesToString(a));
console.log("doFinal參數: |hex :" + bytesToHex(a));
console.log("doFinal結果: |str :" + bytesToString(result));
console.log("doFinal結果: |hex :" + bytesToHex(result));
console.log("doFinal結果: |base64 :" + bytesToBase64(result));
return result;
}
var x509EncodedKeySpec = Java.use('java.security.spec.X509EncodedKeySpec');
x509EncodedKeySpec.$init.overload('[B').implementation = function (a) {
//showStacks();
var result = this.$init(a);
console.log("======================================");
console.log("RSA密鑰:" + bytesToBase64(a));
return result;
}
var rSAPublicKeySpec = Java.use('java.security.spec.RSAPublicKeySpec');
rSAPublicKeySpec.$init.overload('java.math.BigInteger', 'java.math.BigInteger').implementation = function (a, b) {
//showStacks();
var result = this.$init(a, b);
console.log("======================================");
//console.log("RSA密鑰:" + bytesToBase64(a));
console.log("RSA密鑰N:" + a.toString(16));
console.log("RSA密鑰E:" + b.toString(16));
return result;
}
var KeyPairGenerator = Java.use('java.security.KeyPairGenerator');
KeyPairGenerator.generateKeyPair.implementation = function ()
{
//showStacks();
var result = this.generateKeyPair();
console.log("======================================");
var str_private = result.getPrivate().getEncoded();
var str_public = result.getPublic().getEncoded();
console.log("公鑰 |hex" + bytesToHex(str_public));
console.log("私鑰 |hex" + bytesToHex(str_private));
return result;
}
KeyPairGenerator.genKeyPair.implementation = function ()
{
//showStacks();
var result = this.genKeyPair();
console.log("======================================");
var str_private = result.getPrivate().getEncoded();
var str_public = result.getPublic().getEncoded();
console.log("公鑰 |hex" + bytesToHex(str_public));
console.log("私鑰 |hex" + bytesToHex(str_private));
return result;
}
});
視頻演示:https://space.bilibili.com/430241559
相關代碼資料 關注公眾號 恢復關鍵字 frida 下載:
持續更新移動安全,iot安全,編譯原理相關原創視頻文章