Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
Mirai
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
Mirai
Commits
c429a7cf
Commit
c429a7cf
authored
Feb 03, 2020
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix decrypt
parent
e2dd51e0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
129 additions
and
116 deletions
+129
-116
mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/clientToServer.kt
...d/src/jvmTest/kotlin/androidPacketTests/clientToServer.kt
+124
-113
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/cryptor/ECDH.kt
...c/commonMain/kotlin/net.mamoe.mirai/utils/cryptor/ECDH.kt
+5
-3
No files found.
mirai-core-qqandroid/src/jvmTest/kotlin/androidPacketTests/clientToServer.kt
View file @
c429a7cf
...
@@ -68,10 +68,12 @@ internal val t163 = "2C 7A 7B 23 4E 24 3F 24 24 47 62 6B 69 2E 47 50".hexToBytes
...
@@ -68,10 +68,12 @@ internal val t163 = "2C 7A 7B 23 4E 24 3F 24 24 47 62 6B 69 2E 47 50".hexToBytes
var
ecdhPrivateKeyS
=
"97a52992cb7a2110413629af94a3c249c68a3b731510caa8"
var
ecdhPrivateKeyS
=
"97a52992cb7a2110413629af94a3c249c68a3b731510caa8"
internal
val
shareKeyCalculatedByConstPubKey
internal
val
shareKeyCalculatedByConstPubKey
get
()
=
ECDH
.
calculateShareKey
(
by
lazy
{
loadPrivateKey
(
ecdhPrivateKeyS
),
ECDH
.
calculateShareKey
(
initialPublicKey
loadPrivateKey
(
ecdhPrivateKeyS
),
)
initialPublicKey
)
}
var
passwordMd5
:
ByteArray
=
byteArrayOf
()
var
passwordMd5
:
ByteArray
=
byteArrayOf
()
var
uin
:
Long
=
0L
var
uin
:
Long
=
0L
...
@@ -137,132 +139,141 @@ fun ByteReadPacket.analysisOneFullPacket(): ByteReadPacket = debugIfFail("Failed
...
@@ -137,132 +139,141 @@ fun ByteReadPacket.analysisOneFullPacket(): ByteReadPacket = debugIfFail("Failed
println
(
"uin="
+
readString
(
readInt
()
-
4
))
println
(
"uin="
+
readString
(
readInt
()
-
4
))
println
(
"// 解密 body"
)
println
(
"// 解密 body"
)
readRemainingBytes
().
tryDecrypt
().
toReadPacket
().
debugPrintThis
(
"outer body decrypted"
).
apply
{
val
encrypted
=
readRemainingBytes
()
when
(
flag1
)
{
0
x0A
->
decodeSso
()
0
x0B
->
decodeUni
()
else
->
error
(
"unknown flag1: $flag1"
)
}
when
(
flag2
)
{
2
->
{
this
.
debugPrintThis
(
"Oicq Request"
).
apply
{
/*
byte 2 // head flag
short 27 + 2 + remaining.length
ushort client.protocolVersion // const 8001
ushort 0x0001 // const0
uint client.uin
byte 3 // const1
ubyte encryptMethod.value // [EncryptMethod]
byte 0 // const2
int 2 // const3
int client.appClientVersion
int 0 // const4
*/
discardExact
(
3
)
readShort
().
toInt
().
takeIf
{
it
!=
8001
}
?.
let
{
println
(
"这个包不是 oicqRequest"
)
return
@
debugIfFail
this
println
(
" got new protocolVersion=$it"
)
}
val
commandId
=
readUShort
().
toInt
()
println
(
" commandId=0x${commandId.toShort().toUHexString()}"
)
readUShort
().
toInt
().
takeIf
{
it
!=
1
}
?.
let
{
println
(
" got new const0=$it"
)
}
println
(
" uin=${readUInt()}"
)
readByte
().
toInt
().
takeIf
{
it
!=
3
}
?.
let
{
println
(
" got new const1=$it"
)
}
val
encryptionMethod
=
readUByte
().
toInt
()
readByte
().
toInt
().
takeIf
{
it
!=
0
}
?.
let
{
println
(
" got new const2=$it"
)
}
readInt
().
takeIf
{
it
!=
2
}
?.
let
{
println
(
" got new const3=$it"
)
}
readInt
().
takeIf
{
it
!=
0
}
?.
let
{
println
(
" got new appClientVersion=$it"
)
}
readInt
().
takeIf
{
it
!=
0
}
?.
let
{
println
(
" got new const4=$it"
)
}
val
decrypted
=
encrypted
.
tryDecryptOrNull
()
if
(
decrypted
==
null
)
{
println
(
"cannot decrypt: ${encrypted.toUHexString()}"
)
error
(
"cannot decrypt: ${encrypted.toUHexString()}"
)
}
else
{
decrypted
.
toReadPacket
().
debugPrintThis
(
"outer body decrypted"
).
apply
{
when
(
flag1
)
{
0
x0A
->
decodeSso
()
0
x0B
->
decodeUni
()
else
->
error
(
"unknown flag1: $flag1"
)
}
discardExact
(
1
)
when
(
flag2
)
{
discardExact
(
1
)
val
randomKey
=
readBytes
(
16
)
2
->
{
println
(
"randomKey= ${randomKey.toUHexString()}"
)
readUShort
().
toInt
().
takeIf
{
it
!=
258
}
?.
let
{
this
.
debugPrintThis
(
"Oicq Request"
).
apply
{
println
(
" got new const in ECDH head(originally=258)=$it"
)
/*
}
byte 2 // head flag
val
publicKey
=
readBytes
(
readShort
().
toInt
())
short 27 + 2 + remaining.length
println
(
"ecdh publicKey="
+
publicKey
.
toUHexString
())
ushort client.protocolVersion // const 8001
ushort 0x0001 // const0
uint client.uin
byte 3 // const1
ubyte encryptMethod.value // [EncryptMethod]
byte 0 // const2
int 2 // const3
int client.appClientVersion
int 0 // const4
*/
discardExact
(
3
)
readShort
().
toInt
().
takeIf
{
it
!=
8001
}
?.
let
{
println
(
"这个包不是 oicqRequest"
)
return
@
debugIfFail
this
println
(
" got new protocolVersion=$it"
)
}
val
commandId
=
readUShort
().
toInt
()
println
(
" commandId=0x${commandId.toShort().toUHexString()}"
)
readUShort
().
toInt
().
takeIf
{
it
!=
1
}
?.
let
{
println
(
" got new const0=$it"
)
}
println
(
" uin=${readUInt()}"
)
readByte
().
toInt
().
takeIf
{
it
!=
3
}
?.
let
{
println
(
" got new const1=$it"
)
}
val
encryptionMethod
=
readUByte
().
toInt
()
readByte
().
toInt
().
takeIf
{
it
!=
0
}
?.
let
{
println
(
" got new const2=$it"
)
}
readInt
().
takeIf
{
it
!=
2
}
?.
let
{
println
(
" got new const3=$it"
)
}
readInt
().
takeIf
{
it
!=
0
}
?.
let
{
println
(
" got new appClientVersion=$it"
)
}
readInt
().
takeIf
{
it
!=
0
}
?.
let
{
println
(
" got new const4=$it"
)
}
val
encrypt
=
when
(
encryptionMethod
)
{
discardExact
(
1
)
135
,
7
->
{
discardExact
(
1
)
ECDH
.
calculateShareKey
(
val
randomKey
=
readBytes
(
16
)
loadPrivateKey
(
ecdhPrivateKeyS
),
println
(
"randomKey= ${randomKey.toUHexString()}"
)
//"04cb366698561e936e80c157e074cab13b0bb68ddeb2824548a1b18dd4fb6122afe12fe48c5266d8d7269d7651a8eb6fe7".chunkedHexToBytes().adjustToPublicKey() // QQ: 04cb366698561e936e80c157e074cab13b0bb68ddeb2824548a1b18dd4fb6122afe12fe48c5266d8d7269d7651a8eb6fe7
readUShort
().
toInt
().
takeIf
{
it
!=
258
}
?.
let
{
ECDH
.
constructPublicKey
(
"30 46 30 10 06 07 2A 86 48 CE 3D 02 01 06 05 2B 81 04 00 1F 03 32 00"
.
hexToBytes
()
+
publicKey
)
println
(
" got new const in ECDH head(originally=258)=$it"
)
)
}
}
val
publicKey
=
readBytes
(
readShort
().
toInt
())
println
(
"ecdh publicKey="
+
publicKey
.
toUHexString
())
69
->
{
val
encrypt
=
when
(
encryptionMethod
)
{
error
(
"encryptionMethod 69"
)
135
,
7
->
{
ECDH
.
calculateShareKey
(
loadPrivateKey
(
ecdhPrivateKeyS
),
//"04cb366698561e936e80c157e074cab13b0bb68ddeb2824548a1b18dd4fb6122afe12fe48c5266d8d7269d7651a8eb6fe7".chunkedHexToBytes().adjustToPublicKey() // QQ: 04cb366698561e936e80c157e074cab13b0bb68ddeb2824548a1b18dd4fb6122afe12fe48c5266d8d7269d7651a8eb6fe7
ECDH
.
constructPublicKey
(
"30 46 30 10 06 07 2A 86 48 CE 3D 02 01 06 05 2B 81 04 00 1F 03 32 00"
.
hexToBytes
()
+
publicKey
)
)
}
69
->
{
error
(
"encryptionMethod 69"
)
}
else
->
error
(
"unknown encryptionMethod=$encryptionMethod"
)
}
}
else
->
error
(
"unknown encryptionMethod=$encryptionMethod"
)
}
val
encryptedBody
=
readBytes
((
remaining
-
1
).
toInt
())
val
encryptedBody
=
readBytes
((
remaining
-
1
).
toInt
())
val
decrypted
=
kotlin
.
runCatching
{
val
decrypted
=
kotlin
.
runCatching
{
encryptedBody
.
decryptBy
(
encrypt
).
also
{
println
(
"first by calculatedShareKey or sessionKey(method=7)"
)
}
encryptedBody
.
decryptBy
(
encrypt
).
also
{
println
(
"first by calculatedShareKey or sessionKey(method=7)"
)
}
}.
getOrElse
{
encryptedBody
.
decryptBy
(
shareKeyCalculatedByConstPubKey
).
also
{
println
(
"first by shareKeyCalculatedByConstPubKey"
)
}
}.
let
{
firstDecrypted
->
runCatching
{
firstDecrypted
.
decryptBy
(
encrypt
).
also
{
println
(
"second by calculatedShareKey"
)
}
}.
getOrElse
{
}.
getOrElse
{
kotlin
.
runCatching
{
encryptedBody
.
decryptBy
(
shareKeyCalculatedByConstPubKey
).
also
{
println
(
"first by shareKeyCalculatedByConstPubKey"
)
}
firstDecrypted
.
decryptBy
(
shareKeyCalculatedByConstPubKey
)
}.
let
{
firstDecrypted
->
}.
getOrDefault
(
firstDecrypted
)
runCatching
{
firstDecrypted
.
decryptBy
(
encrypt
).
also
{
println
(
"second by calculatedShareKey"
)
}
}.
getOrElse
{
kotlin
.
runCatching
{
firstDecrypted
.
decryptBy
(
shareKeyCalculatedByConstPubKey
)
}.
getOrDefault
(
firstDecrypted
)
}
}
}
}
PacketLogger
.
info
(
"Real body="
+
decrypted
.
toUHexString
())
PacketLogger
.
info
(
"Real body="
+
decrypted
.
toUHexString
())
decrypted
.
toReadPacket
().
apply
{
decrypted
.
toReadPacket
().
apply
{
if
(
commandId
==
0
x0810
)
{
if
(
commandId
==
0
x0810
)
{
DebugLogger
.
info
(
"发送 login!! 正在获取 tgtgtKey"
)
DebugLogger
.
info
(
"发送 login!! 正在获取 tgtgtKey"
)
try
{
try
{
discardExact
(
4
)
discardExact
(
4
)
val
tlvMap
=
readTLVMap
()
val
tlvMap
=
readTLVMap
()
tlvMap
.
printTLVMap
()
tlvMap
.
printTLVMap
()
tlvMap
[
0
x106
]
tlvMap
[
0
x106
]
?.
also
{
DebugLogger
.
info
(
"找到了 0x106"
)
}
?.
also
{
DebugLogger
.
info
(
"找到了 0x106"
)
}
?.
decryptBy
(
md5
(
passwordMd5
+
ByteArray
(
4
)
+
uin
.
toInt
().
toByteArray
()))
?.
decryptBy
(
md5
(
passwordMd5
+
ByteArray
(
4
)
+
uin
.
toInt
().
toByteArray
()))
?.
read
{
?.
read
{
discardExact
(
2
+
4
*
4
+
8
+
4
+
4
+
1
+
16
)
discardExact
(
2
+
4
*
4
+
8
+
4
+
4
+
1
+
16
)
tgtgtKey
=
readBytes
(
16
)
tgtgtKey
=
readBytes
(
16
)
DebugLogger
.
info
(
"获取 tgtgtKey=${tgtgtKey.toUHexString()}"
)
DebugLogger
.
info
(
"获取 tgtgtKey=${tgtgtKey.toUHexString()}"
)
}
?:
DebugLogger
.
info
(
"找不到 0x106"
)
}
?:
DebugLogger
.
info
(
"找不到 0x106"
)
}
catch
(
e
:
Exception
)
{
}
catch
(
e
:
Exception
)
{
e
.
printStackTrace
()
e
.
printStackTrace
()
}
}
}
}
}
}
}
}
}
}
else
->
{
else
->
{
this
.
debugPrintThis
(
"uni packet"
)
this
.
debugPrintThis
(
"uni packet"
)
}
}
}
}
}
}
}
}
}
fun
ByteReadPacket
.
decodeUni
()
{
fun
ByteReadPacket
.
decodeUni
()
{
...
@@ -354,8 +365,8 @@ val keys: Map<String, ByteArray>
...
@@ -354,8 +365,8 @@ val keys: Map<String, ByteArray>
"shareKeyCalculatedByConstPubKey"
to
shareKeyCalculatedByConstPubKey
,
"shareKeyCalculatedByConstPubKey"
to
shareKeyCalculatedByConstPubKey
,
"t108"
to
t108
,
"t108"
to
t108
,
"t10c"
to
t10c
,
"t10c"
to
t10c
,
"t163"
to
t163
"t163"
to
t163
)
)
fun
ByteArray
.
tryDecrypt
():
ByteArray
{
fun
ByteArray
.
tryDecrypt
():
ByteArray
{
return
this
.
tryDecryptOrNull
()
?:
error
(
"Cannot decrypt. Encrypted data="
+
this
.
toUHexString
())
return
this
.
tryDecryptOrNull
()
?:
error
(
"Cannot decrypt. Encrypted data="
+
this
.
toUHexString
())
...
...
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/cryptor/ECDH.kt
View file @
c429a7cf
package
net.mamoe.mirai.utils.cryptor
package
net.mamoe.mirai.utils.cryptor
import
net.mamoe.mirai.utils.io.chunkedHexToBytes
import
net.mamoe.mirai.utils.io.chunkedHexToBytes
import
net.mamoe.mirai.utils.io.toUHexString
expect
interface
ECDHPrivateKey
{
expect
interface
ECDHPrivateKey
{
fun
getEncoded
():
ByteArray
fun
getEncoded
():
ByteArray
...
@@ -65,8 +64,11 @@ private val commonHeadForNot02 = "3046301006072A8648CE3D020106052B8104001F033200
...
@@ -65,8 +64,11 @@ private val commonHeadForNot02 = "3046301006072A8648CE3D020106052B8104001F033200
private
const
val
constantHead
=
"3046301006072A8648CE3D020106052B8104001F03320004"
private
const
val
constantHead
=
"3046301006072A8648CE3D020106052B8104001F03320004"
private
val
byteArray_04
=
byteArrayOf
(
0
x04
)
private
val
byteArray_04
=
byteArrayOf
(
0
x04
)
private
val
head1
=
"302E301006072A8648CE3D020106052B8104001F031A00"
.
chunkedHexToBytes
()
private
val
head2
=
"3046301006072A8648CE3D020106052B8104001F03320004"
.
chunkedHexToBytes
()
fun
ByteArray
.
adjustToPublicKey
():
ECDHPublicKey
{
fun
ByteArray
.
adjustToPublicKey
():
ECDHPublicKey
{
val
head
=
if
(
this
.
size
<
30
)
"302E301006072A8648CE3D020106052B8104001F031A00"
else
"3046301006072A8648CE3D020106052B8104001F03320004"
val
head
=
if
(
this
.
size
<
30
)
head1
else
head2
return
ECDH
.
constructPublicKey
(
(
head
+
this
.
toUHexString
(
""
)).
chunkedHexToBytes
()
)
return
ECDH
.
constructPublicKey
(
head
+
this
)
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment