2235 words
11 minutes
ios喜马拉亚com.gemd.iting登录协议分析
2025-08-22

com.gemd.iting

image-20250822122255092

signature is 40 length, maybe a SHA1. password and account are either AES or RSA(guess). hook SecKeyEncrypt to verify it.

https://www.cnblogs.com/francisblogs/p/7447330.html

SecKeyRef publicKey = ...; // Obtain a public key reference
const uint8_t plainText[] = "Hello, World!";
size_t plainTextLen = strlen((char *)plainText);

uint8_t cipherText[256]; // Allocate buffer for ciphertext
size_t cipherTextLen = sizeof(cipherText);

OSStatus status = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plainText, plainTextLen, cipherText, &cipherTextLen);

if (status == errSecSuccess) {
    printf("Encryption succeeded! Ciphertext length: %zu\n", cipherTextLen);
} else {
    printf("Encryption failed with error code: %d\n", status);
}

we notice that SecKeyEncrypt is for encrypting, so hook it.

https://developer.apple.com/documentation/security/seckeyencrypt(::::::)

Parameters#

  • key

    Public key with which to encrypt the data.

  • padding

    The type of padding to use. Possible values are listed in SecPadding. Typically, PKCS1 is used, which adds PKCS1 padding before encryption. If you specify kSecPaddingNone, the data is encrypted as-is.

  • plainText

    The data to encrypt.

  • plainTextLen

    Length in bytes of the data in the plainText buffer. This must be less than or equal to the value returned by the SecKeyGetBlockSize(_:) function. When PKCS1 padding is performed, the maximum length of data that can be encrypted is 11 bytes less than the value returned by the SecKeyGetBlockSize(_:) function (secKeyGetBlockSize() - 11).

  • cipherText

    On return, the encrypted text.

  • cipherTextLen

    On entry, the size of the buffer provided in the cipherText parameter. On return, the amount of data actually placed in the buffer.

defineHandler({
  onEnter(log, args, state) {
    log('SecKeyEncrypt() onEnter');
    log('SecKeyEncrypt key: ' + hexdump(args[0]));
    log('SecKeyEncrypt padding: ' + args[1].toInt32());
    log('SecKeyEncrypt plainText: ' + args[2].readCString());
    log('SecKeyEncrypt plainTextLen: ' + args[3].toInt32());
    this.args4 = args[4];
    this.args5 = args[5];
  },

  onLeave(log, retval, state) {
    log('SecKeyEncrypt cipherText: ' + hexdump(this.args4, {length: 128}));
    log('SecKeyEncrypt cipherTextLen: ' + this.args5.readInt());
  }
});
// frida-trace -U -N com.gemd.iting -i CC_MD5 -i CCCrypt -i SecKeyEncrypt

heres the output

           /* TID 0x103 */
   174 ms  SecKeyEncrypt() onEnter
   174 ms  SecKeyEncrypt key:             0  1  2  3  4  5  6  7  8  9  A  B  
C  D  E  F  0123456789ABCDEF
2831f1840  11 7c 74 f5 a1 21 00 00 80 18 01 00 03 00 00 00  .|t..!..........  
2831f1850  80 65 43 f6 01 00 00 00 30 9e 92 34 01 00 00 00  .eC.....0..4....  
2831f1860  b3 bf 76 f5 a1 21 00 00 20 db c6 81 02 00 00 00  ..v..!.. .......  
2831f1870  00 00 00 00 00 00 00 00 40 03 1f 83 02 00 00 00  ........@.......  
2831f1880  31 70 74 f5 a1 21 00 00 85 16 00 00 01 00 00 00  1pt..!..........  
2831f1890  00 00 00 00 00 70 6a 40 00 00 00 00 00 00 00 00  .....pj@........  
2831f18a0  10 61 70 70 6c 69 63 61 74 69 6f 6e 2f 6a 73 6f  .application/jso  
2831f18b0  6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  n...............  
2831f18c0  91 6f 74 f5 a1 21 00 00 8c 07 00 00 01 00 00 00  .ot..!..........  
2831f18d0  0b 70 32 73 70 5f 73 77 69 74 63 68 00 00 00 00  .p2sp_switch....  
2831f18e0  e1 88 74 f5 a1 21 00 00 60 d5 08 38 01 00 00 00  ..t..!..`..8....  
2831f18f0  44 00 00 00 14 00 00 14 00 00 00 00 00 00 00 00  D...............  
2831f1900  11 7c 74 f5 a1 21 00 00 80 14 01 00 02 00 00 00  .|t..!..........  
2831f1910  58 41 e8 eb 01 00 00 00 40 9c dc 82 02 00 00 00  XA......@.......  
2831f1920  e1 88 74 f5 a1 21 00 00 00 a0 d7 19 01 00 00 00  ..t..!..........  
2831f1930  16 00 00 80 0c 00 00 10 00 00 00 00 00 00 00 00  ................  
   174 ms  SecKeyEncrypt padding: 1
   174 ms  SecKeyEncrypt plainText: 15575625896
   174 ms  SecKeyEncrypt plainTextLen: 11
   175 ms  SecKeyEncrypt cipherText:             0  1  2  3  4  5  6  7  8  9 
 A  B  C  D  E  F  0123456789ABCDEF
285956f80  4d 10 0b da 2e 6c 40 53 cb 21 36 bd 09 58 af 8e  M....l@S.!6..X..  
285956f90  92 55 e0 34 d8 f0 92 ae 6e be b9 4f 96 92 3d 1f  .U.4....n..O..=.  
285956fa0  cc 68 53 ed 8c 83 55 25 a9 c2 d1 09 0a db bb 5d  .hS...U%.......]  
285956fb0  56 80 ab e8 66 50 d8 be 0f cf a2 c1 67 b7 e5 f5  V...fP......g...  
285956fc0  1f 30 ba af 46 4f d7 ad 3e 4e fc f5 7e aa 6a 8e  .0..FO..>N..~.j.  
285956fd0  f7 e4 23 1a 15 79 0a 7c 93 97 ef c7 19 16 01 83  ..#..y.|........  
285956fe0  21 7d aa 2f 79 47 8a ae 06 de 82 fb 2f 16 23 c9  !}./yG....../.#.  
285956ff0  f7 68 a4 88 b1 d1 fd 3c 3d 5d 81 6d 0f e6 ca 65  .h.....<=].m...e  
   175 ms  SecKeyEncrypt cipherTextLen: 128
   177 ms  SecKeyEncrypt() onEnter
   177 ms  SecKeyEncrypt key:             0  1  2  3  4  5  6  7  8  9  A  B  
C  D  E  F  0123456789ABCDEF
2831f3980  11 7c 74 f5 a1 21 00 00 80 18 01 00 03 00 00 00  .|t..!..........  
2831f3990  80 65 43 f6 01 00 00 00 a0 ae 99 34 01 00 00 00  .eC........4....  
2831f39a0  70 d5 e7 eb 01 00 00 00 02 00 00 00 00 00 00 00  p...............  
2831f39b0  02 00 00 00 00 00 00 00 40 75 dd 19 01 00 00 00  ........@u......  
2831f39c0  b1 bf 76 f5 a1 21 00 00 00 f1 c6 81 02 00 00 00  ..v..!..........  
2831f39d0  00 00 00 00 00 00 00 00 c0 29 1f 83 02 00 00 00  .........)......  
2831f39e0  11 7c 74 f5 a1 21 00 00 80 14 01 00 01 00 00 00  .|t..!..........  
2831f39f0  58 41 e8 eb 01 00 00 00 00 b1 dd 82 02 00 00 00  XA..............  
2831f3a00  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................  
2831f3a10  a0 3f 88 83 02 00 00 00 6f 72 69 65 73 00 00 00  .?......ories...  
2831f3a20  21 45 75 f5 a1 21 00 00 f4 17 46 c5 4d 09 4e a9  !Eu..!....F.M.N.  
2831f3a30  82 cb 15 f3 9b 80 2d 42 00 00 00 00 00 00 00 00  ......-B........  
2831f3a40  91 6f 74 f5 a1 21 00 00 c0 07 00 00 01 00 00 00  .ot..!..........  
2831f3a50  c9 3e 26 9b 01 00 00 00 11 00 00 00 00 00 00 00  .>&.............  
2831f3a60  31 89 74 f5 a1 41 00 00 c0 c8 f9 81 02 00 00 00  1.t..A..........  
2831f3a70  11 00 00 00 06 00 00 08 c0 3d 53 83 02 00 00 00  .........=S.....  
   177 ms  SecKeyEncrypt padding: 1
   177 ms  SecKeyEncrypt plainText: 123456
   177 ms  SecKeyEncrypt plainTextLen: 6
   179 ms  SecKeyEncrypt cipherText:             0  1  2  3  4  5  6  7  8  9 
 A  B  C  D  E  F  0123456789ABCDEF
285954f80  52 23 a4 4e d8 98 3e fb b2 6d 47 10 21 13 38 55  R#.N..>..mG.!.8U  
285954f90  c5 44 6f d8 99 51 fd 25 ba aa 92 6a 6e ad 3c 8a  .Do..Q.%...jn.<.  
285954fa0  b5 25 46 8f 02 72 db 01 5b 13 d5 84 15 af 58 b4  .%F..r..[.....X.  
285954fb0  f0 0e 1b 17 62 0f 51 a0 93 2c 55 37 0c 0a e1 7a  ....b.Q..,U7...z  
285954fc0  8b 07 30 ee dc cb 1b 97 1f 7d 8c bd c5 94 bd ce  ..0......}......  
285954fd0  ca 70 71 a6 09 04 86 92 f5 e8 5f 06 e0 bc 57 47  .pq......._...WG  
285954fe0  f6 d6 ff ea 63 5f f3 d9 75 18 40 38 07 21 c4 11  ....c_..u.@8.!..  
285954ff0  bd 75 30 74 bf 20 0c 99 20 e1 c6 b2 a7 88 ea a2  .u0t. .. .......  
   179 ms  SecKeyEncrypt cipherTextLen: 128

and we can see its the same as in Charles

image-20250822213447326

image-20250822213521708

charles:

{
	"fdsOtp": "7278949236029428025",
	"account": "TRAL2i5sQFPLITa9CVivjpJV4DTY8JKubr65T5aSPR\/MaFPtjINVJanC0QkK27tdVoCr6GZQ2L4Pz6LBZ7fl9R8wuq9GT9etPk789X6qao735CMaFXkKfJOX78cZFgGDIX2qL3lHiq4G3oL7LxYjyfdopIix0f08PV2BbQ\/mymU=",
	"password": "UiOkTtiYPvuybUcQIRM4VcVEb9iZUf0luqqSam6tPIq1JUaPAnLbAVsT1YQVr1i08A4bF2IPUaCTLFU3DArheosHMO7cyxuXH32MvcWUvc7KcHGmCQSGkvXoXwbgvFdH9tb\/6mNf89l1GEA4ByHEEb11MHS\/IAyZIOHGsqeI6qI=",
	"nonce": "0-A0694F26B7500e313c5ff3e96facb1a71542dfd9c621f85cf27a0efbd7eb60",
	"signature": "7209062e7f1f069456456ad858b28eddd93e4c59"
}

also try SHA1

defineHandler({
  onEnter(log, args, state) {
    log('CC_SHA1() onEnter: ');
    log(args[0].readCString());
    this.args2 = args[2];
  },

  onLeave(log, retval, state) {
    log('CC_SHA1() onLeave: ');
    log(hexdump(this.args2))
  }
});
// frida-trace -U -N com.gemd.iting -i CC_SHA1
269804 ms  CC_SHA1() onEnter: 
269804 ms  ACCOUNT=GS8RXU6TEZV67EIZZGK1HXVF3JUUK6LMU0U2FV6RGITNT79O8EYEXUSBDKGM7BXVLFJCUV6PCCRMA7GI4EBIO6UL1BFNTQKNFZSBWKJXSFIWKJCZDAIW9P9VQRGON02GB2EOBTODVFVIF/NHZFKMEMD5DEKFCIGVFE2JR
NHS29W=&FDSOTP=8289878198832600662&NONCE=0-A8CCB2313AA723366B2BE09BD88292CDC9B39F737030A2D211D1B1B2121A6C&PASSWORD=CXLPWTCTRBHYNYO4OVHTASCOCL2ORTPYOMTPK3N0V29VLAYU5MEPMSDCTKWWVDSPL3E5V
3CZUUAFCMEIBE2ZZY2JEIL/OQ/DFK3GRBHYMIMNS5NWJ2TDUV1+BNB49JQY/LGNSKIHRCTL5RA8F5IRITODWQOB+ZUBZAFKQSDVIM4=&MOBILE-V1-PRODUCT-7D74899B338B4F348E2383970CC09991E8E8D8F2BC744EF0BEE94D76D718C0
89
269805 ms  CC_SHA1() onLeave:              
           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
16b0de234  f7 6c 22 80 d1 38 29 e7 de 2a 8a e9 8f ec ed 51  .l"..8)..*.....Q
16b0de244  14 d6 2b f8 45 00 5a b6 de 8a b1 bf f0 b0 8e 83  ..+.E.Z.........
16b0de254  02 00 00 00 98 90 9a 0f 01 00 00 00 f0 24 75 f5  .............$u.
16b0de264  01 00 00 00 04 00 00 00 00 00 00 00 70 a6 8e 83  ............p...
16b0de274  02 00 00 00 60 59 6f 83 02 00 00 00 d0 e3 0d 6b  ....`Yo........k
16b0de284  01 00 00 00 e8 9e 3c 07 01 00 00 00 f0 b0 8e 83  ......<.........
16b0de294  02 00 00 00 98 90 9a 0f 01 00 00 00 00 00 00 00  ................
16b0de2a4  00 00 00 00 60 94 73 83 02 00 00 00 ff ff ff ff  ....`.s.........
16b0de2b4  ff ff ff ff 00 80 76 83 02 00 00 00 98 80 db 80  ......v.........
16b0de2c4  01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
16b0de2d4  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
16b0de2e4  00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00  ................
16b0de2f4  00 00 00 00 a8 2c b7 fa 01 00 00 00 58 9b 81 0f  .....,......X...
16b0de304  01 00 00 00 f8 80 7c 0f 01 00 00 00 40 e3 0d 6b  ......|.....@..k
16b0de314  01 00 00 00 88 38 ac 80 01 00 00 00 07 00 00 00  .....8..........
16b0de324  00 00 00 00 a8 2c b7 fa 01 00 00 00 07 00 00 00  .....,..........

the same with signature captured in Charles

{
	"fdsOtp": "8289878198832600662",
	"account": "Gs8Rxu6TeZV67eizzgK1Hxvf3jUUk6LMu0u2FV6RgITnT79O8eYeXusbdKgm7bxvLFjCuv6PccRMa7gi4Ebio6uL1BfNTQKnFZSBWKjXSfiWkjCzDAiw9p9vqrGOn02Gb2eoBTodvFVIf\/nHzFKMEmD5DEKFCiGvFe2jRnHS29w=",
	"password": "CxlpWtCTrBhyNYO4ovHtaScOcL2orTpyomtpK3n0v29VlAyU5mEPMSDCTkwWVdsPL3e5V3cZUUafCMeIbe2zzY2jEIl\/Oq\/DFK3GrBHyMimNS5nWJ2TdUV1+Bnb49JqY\/lgnSkIHrcTl5Ra8f5irItOdwQob+zUBzaFkqSDVIM4=",
	"nonce": "0-A8CCB2313AA723366b2be09bd88292cdc9b39f737030a2d211d1b1b2121a6c",
	"signature": "f76c2280d13829e7de2a8ae98feced5114d62bf8"
}

next step, we need to find out the key.

add this line in SecKeyEncrypt.js

    log('SecKeyEncrypt called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');

so we can get this trace

           /* TID 0x103 */
  4045 ms  SecKeyEncrypt() onEnter ---------------------------
  4045 ms  SecKeyEncrypt called from:
0x1070a737c /private/var/containers/Bundle/Application/8B824585-3B01-449C-BEBA-29
C32A9C0276/ting.app/ting!-[XMRSAEncryptor RSAEncrypotoTheData:]
0x1070a6e18 /private/var/containers/Bundle/Application/8B824585-3B01-449C-BEBA-29
C32A9C0276/ting.app/ting!-[XMRSAEncryptor encryptWithRawString:]
0x107085384 /private/var/containers/Bundle/Application/8B824585-3B01-449C-BEBA-29
C32A9C0276/ting.app/ting!+[NSString RSAStringFromString:]
0x106cad5e4 /private/var/containers/Bundle/Application/8B824585-3B01-449C-BEBA-29
C32A9C0276/ting.app/ting!+[XMAccountManager loginWithAccount:fdsOtp:psw:]        
0x106d044a4 ting!0x26f84a4 (0x1026f84a4)
0x105d7af50 ting!0x176ef50 (0x10176ef50)
0x105d7a028 ting!0x176e028 (0x10176e028)
0x105d7ef0c ting!0x1772f0c (0x101772f0c)
0x180807094 libdispatch.dylib!_dispatch_call_block_and_release
0x180808094 libdispatch.dylib!_dispatch_client_callout
0x1807b4d44 libdispatch.dylib!_dispatch_main_queue_drain
0x1807b4994 libdispatch.dylib!_dispatch_main_queue_callback_4CF$VARIANT$mp       
0x180b03014 CoreFoundation!__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__    
0x180ac04f8 CoreFoundation!__CFRunLoopRun
0x180ad3174 CoreFoundation!CFRunLoopRunSpecific
0x1a15f2988 GraphicsServices!GSEventRunModal

search RSAEncrypotoTheData function in IDA.

it’s nothing, why tf its different with the tutorial !!! fine i just screenshot the tutorial :/

image-20250823200405086

i only found this shit

__SecKey *__cdecl -[XMRSAEncryptor getPublicKeyFromCertification](XMRSAEncryptor *self, SEL a2)
{
  void *v2; // x0
  id v3; // x20
  void *v4; // x0
  id v5; // x19
  void *v6; // x0
  id v7; // x20
  __int64 v8; // x21
  void *v9; // x0
  id v10; // x22
  __int64 v11; // x21
  void *v12; // x0
  id v13; // x23
  void *v14; // x0
  id v15; // x0
  const __CFData *v16; // x22
  SecCertificateRef v17; // x23
  SecPolicyRef v18; // x24
  __SecKey *v19; // x23
  id v20; // x21
  int v22; // [xsp+54h] [xbp+14h] BYREF
  SecTrustRef v23; // [xsp+58h] [xbp+18h] BYREF

  +[NSObject DYOpen_class]_0_0();
  v2 = (void *)sub_108CBCE00(&OBJC_CLASS___NSBundle);
  v3 = objc_retainAutoreleasedReturnValue(v2);
  v4 = (void *)((__int64 (*)(void))sub_108E78880)();
  v5 = objc_retainAutoreleasedReturnValue(v4);
  objc_release(v3);
  v6 = (void *)sub_108CBD280(&OBJC_CLASS___NSBundle);
  v7 = objc_retainAutoreleasedReturnValue(v6);
  v9 = (void *)sub_108CD0FA0(v8);
  v10 = objc_retainAutoreleasedReturnValue(v9);
  v12 = (void *)sub_108CD0FC0(v11);
  v13 = objc_retainAutoreleasedReturnValue(v12);
  v14 = (void *)sub_108E78880(v7);
  objc_retainAutoreleasedReturnValue(v14);
  objc_release(v13);
  objc_release(v10);
  v15 = objc_alloc((Class)&OBJC_CLASS___NSData);
  v16 = (const __CFData *)sub_108DBB460(v15);
  v17 = SecCertificateCreateWithData(kCFAllocatorDefault, v16);
  v18 = SecPolicyCreateBasicX509();
  if ( !SecTrustCreateWithCertificates(v17, v18, &v23) )
    SecTrustEvaluate(v23, (SecTrustResultType *)&v22);
  CFRelease(v17);
  CFRelease(v18);
  v19 = SecTrustCopyPublicKey(v23);
  objc_release(v16);
  objc_release(v20);
  objc_release(v7);
  objc_release(v5);
  return v19;
}

compared with the code in here and checkout the document

image-20250823200844687

frida-trace -U -N com.gemd.iting -m "-[NSData initWithContentsOfFile:]"

originally, its logs are like

           /* TID 0x1bc3b */
 52117 ms  -[NSData initWithContentsOfFile:0x13c7f89e0]
           /* TID 0x1df4b */
 96390 ms  -[NSData initWithContentsOfFile:0x2819280e0]

the script is like

  onEnter(log, args, state) {
    log(`-[NSData initWithContentsOfFile:${args[2]}]`);
  },

use log(ObjC.Object(args[2])); to get the real content in args[2]

defineHandler({
  onEnter(log, args, state) {
    log(`-[NSData initWithContentsOfFile:${args[2]}]`);
    log(ObjC.Object(args[2]));
  },

  onLeave(log, retval, state) {
  }
});
// frida-trace -U -N com.gemd.iting -m "-[NSData initWithContentsOfFile:]"
 47000 ms  -[NSData initWithContentsOfFile:0x28124df80]
 47000 ms  /var/containers/Bundle/Application/8B824585-3B01-449C-BEBA-29C32A9C0276/ting.app/XMCategories.bundle/public_key.der
 47025 ms  -[NSData initWithContentsOfFile:0x2812215f0]
 47025 ms  /var/containers/Bundle/Application/8B824585-3B01-449C-BEBA-29C32A9C0276/ting.app/XMCategories.bundle/public_key.der

so we need to get this der certificate

double click it and copy it as Base64 encode X.509(*.cer) format.

then we need to extract the public key from this .cer file

-----BEGIN CERTIFICATE-----
MIICSTCCAbICCQDZsrkJujMlfjANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJD
TjERMA8GA1UECBMIU2hhbmdIYWkxETAPBgNVBAcTCFNoYW5nSGFpMREwDwYDVQQK
EwhYaW1hbGF5YTERMA8GA1UECxMIWGltYWxheWExDjAMBgNVBAMTBWl0aW5nMB4X
DTE1MDgzMTAyNTMzN1oXDTI1MDgyODAyNTMzN1owaTELMAkGA1UEBhMCQ04xETAP
BgNVBAgTCFNoYW5nSGFpMREwDwYDVQQHEwhTaGFuZ0hhaTERMA8GA1UEChMIWGlt
YWxheWExETAPBgNVBAsTCFhpbWFsYXlhMQ4wDAYDVQQDEwVpdGluZzCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAlYWkdzq+7LlJcB1Jdi8t+rlZm6Gd/h4aL6IA
4y4ERPQm2lKJEtnqhmlRX28QFMRU4TQ7l6v3wQ/knVIKaZnGayMOBzDD+ALRNqiS
UB/ysT1pm1x+y7/vQorDbT2Dpb1ifxh0an/cd0wSo43idgo7lcZTwQ1+t/hHIpdi
UfZJVWsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBZw0agfIA+fb8QA8/NnNiXD3a/
GccIVs4j0bV2b9QE//zi5ULGIWHxIzNsXONO7iHs03A52IIYb5UL6k7m7dSYUKKI
KMxi1FrIS0JBAN2vIC1qU55joN/5qgj9e5U7g5QSwBk7r2QSaRgGAWXxbw9wYo7M
pBxmxcvf9WMY8Unx/w==
-----END CERTIFICATE-----

and also copy RSA from it and remove all spaces

image-20250823195507892

0203 is a splitter, 010001 is the publicExponent. remove 30818902818100 in front of this shit, remain is the module

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;

import java.io.ByteArrayInputStream;

public class Main {
    public static String modulus = "9585a4773abeecb949701d49762f2dfab9599ba19dfe1e1a2fa200e32e0444f426da528912d9ea8669515f6f1014c454e1343b97abf7c10fe49d520a6999c66b230e0730c3f802d136a892501ff2b13d699b5c7ecbbfef428ac36d3d83a5bd627f18746a7fdc774c12a38de2760a3b95c653c10d7eb7f84722976251f649556b0203010001";

    public static String publicExponent = "010001";

    public static String certificate = "-----BEGIN CERTIFICATE-----\n" +
            "MIICSTCCAbICCQDZsrkJujMlfjANBgkqhkiG9w0BAQUFADBpMQswCQYDVQQGEwJD\n" +
            "TjERMA8GA1UECBMIU2hhbmdIYWkxETAPBgNVBAcTCFNoYW5nSGFpMREwDwYDVQQK\n" +
            "EwhYaW1hbGF5YTERMA8GA1UECxMIWGltYWxheWExDjAMBgNVBAMTBWl0aW5nMB4X\n" +
            "DTE1MDgzMTAyNTMzN1oXDTI1MDgyODAyNTMzN1owaTELMAkGA1UEBhMCQ04xETAP\n" +
            "BgNVBAgTCFNoYW5nSGFpMREwDwYDVQQHEwhTaGFuZ0hhaTERMA8GA1UEChMIWGlt\n" +
            "YWxheWExETAPBgNVBAsTCFhpbWFsYXlhMQ4wDAYDVQQDEwVpdGluZzCBnzANBgkq\n" +
            "hkiG9w0BAQEFAAOBjQAwgYkCgYEAlYWkdzq+7LlJcB1Jdi8t+rlZm6Gd/h4aL6IA\n" +
            "4y4ERPQm2lKJEtnqhmlRX28QFMRU4TQ7l6v3wQ/knVIKaZnGayMOBzDD+ALRNqiS\n" +
            "UB/ysT1pm1x+y7/vQorDbT2Dpb1ifxh0an/cd0wSo43idgo7lcZTwQ1+t/hHIpdi\n" +
            "UfZJVWsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBZw0agfIA+fb8QA8/NnNiXD3a/\n" +
            "GccIVs4j0bV2b9QE//zi5ULGIWHxIzNsXONO7iHs03A52IIYb5UL6k7m7dSYUKKI\n" +
            "KMxi1FrIS0JBAN2vIC1qU55joN/5qgj9e5U7g5QSwBk7r2QSaRgGAWXxbw9wYo7M\n" +
            "pBxmxcvf9WMY8Unx/w==\n" +
            "-----END CERTIFICATE-----";

    public static void main(String[] args) throws Exception {
        BigInteger n = new BigInteger(modulus, 16);
        BigInteger e = new BigInteger(publicExponent, 16);
        RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(n, e);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey pubkey = keyFactory.generatePublic(rsaPublicKeySpec);
        byte[] encoded = pubkey.getEncoded();
        byte[] encode = Base64.getEncoder().encode(encoded);
        System.out.println(new String(encode));

        CertificateFactory finalcf = CertificateFactory.getInstance("X.509");
        X509Certificate realCertificate = (X509Certificate)finalcf.generateCertificate(new ByteArrayInputStream(certificate.getBytes()));
        encode = Base64.getEncoder().encode(realCertificate.getPublicKey().getEncoded());
        System.out.println(new String(encode));
    }
}
ios喜马拉亚com.gemd.iting登录协议分析
https://zycreverse.netlify.app/posts/iosximalaya/
Author
会写点代码的本子画手
Published at
2025-08-22