From c478f24db085d88e6c1148dc32003e453cf70650 Mon Sep 17 00:00:00 2001 From: Him188 Date: Wed, 16 Dec 2020 21:56:20 +0800 Subject: [PATCH] Update to 8.4.18 --- .../kotlin/utils/BotConfiguration.kt | 2 +- .../kotlin/network/QQAndroidClient.kt | 5 +-- .../network/protocol/packet/EncryptMethod.kt | 40 +++++++++++-------- .../kotlin/network/protocol/packet/Tlv.kt | 2 +- .../network/protocol/packet/login/WtLogin.kt | 3 +- .../commonMain/kotlin/utils/cryptor/ECDH.kt | 21 +++++++--- .../jvmMain/kotlin/utils/cryptor/ECDHJvm.kt | 16 +++++--- 7 files changed, 56 insertions(+), 33 deletions(-) diff --git a/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt b/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt index e9f210bb6..226fe0d8e 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt +++ b/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.kt @@ -215,7 +215,7 @@ public open class BotConfiguration { // open for Java /** * Android 手机. */ - ANDROID_PHONE(537062845), + ANDROID_PHONE(537066439), /** * Android 平板. diff --git a/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt b/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt index af0c77d6d..8b3dac3f4 100644 --- a/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt +++ b/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt @@ -29,7 +29,6 @@ import net.mamoe.mirai.internal.utils.cryptor.TEA import net.mamoe.mirai.network.LoginFailedException import net.mamoe.mirai.network.NoServerAvailableException import net.mamoe.mirai.utils.* -import kotlin.jvm.Volatile import kotlin.random.Random internal val DeviceInfo.guid: ByteArray get() = generateGuid(androidId, macAddress) @@ -158,8 +157,8 @@ internal open class QQAndroidClient( var openAppId: Long = 715019303L - val apkVersionName: ByteArray get() = "8.4.8".toByteArray() - val buildVer: String get() = "8.4.8.4810" // 8.2.0.1296 // 8.4.8.4810 // 8.2.7.4410 + val apkVersionName: ByteArray get() = "8.4.18".toByteArray() + val buildVer: String get() = "8.4.18.4810" // 8.2.0.1296 // 8.4.8.4810 // 8.2.7.4410 private val messageSequenceId: AtomicInt = atomic(22911) internal fun atomicNextMessageSequenceId(): Int = messageSequenceId.getAndAdd(2) diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/EncryptMethod.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/EncryptMethod.kt index 319580ddd..8d4e2b1f4 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/EncryptMethod.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/EncryptMethod.kt @@ -59,7 +59,7 @@ internal class EncryptMethodECDH135(override val ecdh: ECDH) : internal class EncryptMethodECDH7(override val ecdh: ECDH) : EncryptMethodECDH { - override val id: Int get() = 7 + override val id: Int get() = 7 // 135 } internal interface EncryptMethodECDH : EncryptMethod { @@ -73,22 +73,30 @@ internal interface EncryptMethodECDH : EncryptMethod { val ecdh: ECDH - override fun makeBody(client: QQAndroidClient, body: BytePacketBuilder.() -> Unit): ByteReadPacket = - buildPacket { - writeByte(1) // const - writeByte(1) // const - writeFully(client.randomKey) - writeShort(258) // const + override fun makeBody(client: QQAndroidClient, body: BytePacketBuilder.() -> Unit): ByteReadPacket = buildPacket { + /* //new curve p-256 + writeByte(2) // const + writeByte(1) // const + writeFully(client.randomKey) + writeShort(0x0131) // const + writeShort(0x0001) + */ - if (ecdh.keyPair === ECDHKeyPair.DefaultStub) { - writeShortLVByteArray(ECDHKeyPair.DefaultStub.defaultPublicKey) - encryptAndWrite(ECDHKeyPair.DefaultStub.defaultShareKey, body) - } else { - writeShortLVByteArray(ecdh.keyPair.publicKey.getEncoded().drop(23).take(49).toByteArray().also { - check(it[0].toInt() == 0x04) { "Bad publicKey generated. Expected first element=0x04, got${it[0]}" } - }) + writeByte(1) // version + writeByte(1) // const + writeFully(client.randomKey) + writeShort(0x0102) - encryptAndWrite(ecdh.keyPair.initialShareKey, body) - } + if (ecdh.keyPair === ECDHKeyPair.DefaultStub) { + writeShortLVByteArray(ECDHKeyPair.DefaultStub.defaultPublicKey) + encryptAndWrite(ECDHKeyPair.DefaultStub.defaultShareKey, body) + } else { + // for p-256, drop(26). // but not really sure. + writeShortLVByteArray(ecdh.keyPair.publicKey.getEncoded().drop(23).toByteArray().also { + check(it[0].toInt() == 0x04) { "Bad publicKey generated. Expected first element=0x04, got${it[0]}" } + }) + + encryptAndWrite(ecdh.keyPair.initialShareKey, body) } + } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/Tlv.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/Tlv.kt index 8d75cde56..7efb6f193 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/Tlv.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/Tlv.kt @@ -103,7 +103,7 @@ internal fun BytePacketBuilder.t106( encryptAndWrite(MiraiPlatformUtils.md5(passwordMd5 + ByteArray(4) + (salt.takeIf { it != 0L } ?: uin).toInt().toByteArray())) { writeShort(4)//TGTGTVer writeInt(Random.nextInt()) - writeInt(5)//ssoVer + writeInt(13)//ssoVer writeInt(appId.toInt()) writeInt(appClientVersion) diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/WtLogin.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/WtLogin.kt index 1ec66ff04..ba21cf4db 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/WtLogin.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/WtLogin.kt @@ -160,7 +160,7 @@ internal class WtLogin { */ t116(client.miscBitMap, client.subSigMap) t100(appId, client.subAppId, client.appClientVersion) - t107(0) + t107(6) // t108(byteArrayOf()) // ignored: t104() @@ -312,6 +312,7 @@ internal class WtLogin { discardExact(2) val tlvMap: TlvMap = this._readTLVMap() // tlvMap.printTLVMap() + tlvMap[0x161]?.let { bot.client.analysisTlv161(it) } return when (type.toInt()) { 0 -> onLoginSuccess(tlvMap, bot) 2 -> onSolveLoginCaptcha(tlvMap, bot) diff --git a/mirai-core/src/commonMain/kotlin/utils/cryptor/ECDH.kt b/mirai-core/src/commonMain/kotlin/utils/cryptor/ECDH.kt index 1d0456baf..6d7fe372f 100644 --- a/mirai-core/src/commonMain/kotlin/utils/cryptor/ECDH.kt +++ b/mirai-core/src/commonMain/kotlin/utils/cryptor/ECDH.kt @@ -76,13 +76,24 @@ internal expect class ECDH(keyPair: ECDHKeyPair) { @Suppress("FunctionName") internal expect fun ECDH(): ECDH +// gen by p-256 +//3059301306072A8648CE3D020106082A8648CE3D03010703420004FA540CB3F755D0A6572338777A4D0BEAFA86664D53040B27331CBF1B7F3C226CE8A1C05EFA9028F85510B103D8175172895C9F9FE4C80A47894BCA2BE569BFCB +//3059301306072A8648CE3D020106082A8648CE3D03010703420004949D41D7C14B92F0CB94B6232FB87BA51B0D5AB661FBAF95599A97472FFC4F50BC8CEC5865E79DB3782459A6E9A2298954CD198A25274CEEA8F925342D763D62 + +/* +// p-256 + get() = ECDH.constructPublicKey( + ("3059301306072A8648CE3D020106082A8648CE3D03010703420004" + + "EBCA94D733E399B2DB96EACDD3F69A8BB0F74224E2B44E3357812211D2E62EFB" + + "C91BB553098E25E33A799ADC7F76FEB208DA7C6522CDB0719A305180CC54A82E" + ).chunkedHexToBytes() + ) +* */ + + +// this is for old curve internal val initialPublicKey get() = ECDH.constructPublicKey("3046301006072A8648CE3D020106052B8104001F03320004928D8850673088B343264E0C6BACB8496D697799F37211DEB25BB73906CB089FEA9639B4E0260498B51A992D50813DA8".chunkedHexToBytes()) -private val commonHeadFor02 = "302E301006072A8648CE3D020106052B8104001F031A00".chunkedHexToBytes() -private val commonHeadForNot02 = "3046301006072A8648CE3D020106052B8104001F033200".chunkedHexToBytes() -private const val constantHead = "3046301006072A8648CE3D020106052B8104001F03320004" -private val byteArray_04 = byteArrayOf(0x04) - private val head1 = "302E301006072A8648CE3D020106052B8104001F031A00".chunkedHexToBytes() private val head2 = "3046301006072A8648CE3D020106052B8104001F03320004".chunkedHexToBytes() diff --git a/mirai-core/src/jvmMain/kotlin/utils/cryptor/ECDHJvm.kt b/mirai-core/src/jvmMain/kotlin/utils/cryptor/ECDHJvm.kt index c4558e463..a64d76ac7 100644 --- a/mirai-core/src/jvmMain/kotlin/utils/cryptor/ECDHJvm.kt +++ b/mirai-core/src/jvmMain/kotlin/utils/cryptor/ECDHJvm.kt @@ -28,8 +28,7 @@ internal actual class ECDHKeyPairImpl( override val privateKey: ECDHPrivateKey get() = delegate.private override val publicKey: ECDHPublicKey get() = delegate.public - override val initialShareKey: ByteArray = - ECDH.calculateShareKey(privateKey, initialPublicKey) + override val initialShareKey: ByteArray by lazy { ECDH.calculateShareKey(privateKey, initialPublicKey) } } @Suppress("FunctionName") @@ -38,6 +37,8 @@ internal actual fun ECDH() = internal actual class ECDH actual constructor(actual val keyPair: ECDHKeyPair) { actual companion object { + private const val curveName = "secp192k1" // p-256 + actual val isECDHAvailable: Boolean init { @@ -45,7 +46,7 @@ internal actual class ECDH actual constructor(actual val keyPair: ECDHKeyPair) { fun testECDH() { ECDHKeyPairImpl( KeyPairGenerator.getInstance("ECDH") - .also { it.initialize(ECGenParameterSpec("secp192k1")) } + .also { it.initialize(ECGenParameterSpec(curveName)) } .genKeyPair()).let { calculateShareKey(it.privateKey, it.publicKey) } @@ -60,6 +61,8 @@ internal actual class ECDH actual constructor(actual val keyPair: ECDHKeyPair) { } Security.addProvider(BouncyCastleProvider()) testECDH() + }.onFailure { + it.printStackTrace() }.isSuccess } @@ -67,9 +70,10 @@ internal actual class ECDH actual constructor(actual val keyPair: ECDHKeyPair) { if (!isECDHAvailable) { return ECDHKeyPair.DefaultStub } - return ECDHKeyPairImpl(KeyPairGenerator.getInstance("ECDH") - .also { it.initialize(ECGenParameterSpec("secp192k1")) } - .genKeyPair()) + return ECDHKeyPairImpl( + KeyPairGenerator.getInstance("ECDH") + .also { it.initialize(ECGenParameterSpec(curveName)) } + .genKeyPair()) } actual fun calculateShareKey(