diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/OutgoingPacket.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/OutgoingPacket.kt
index a2f8a2dfd..4f9fbaf1f 100644
--- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/OutgoingPacket.kt
+++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/OutgoingPacket.kt
@@ -21,6 +21,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.sso.TRpcRawPacket
 import net.mamoe.mirai.internal.spi.EncryptService
 import net.mamoe.mirai.internal.spi.EncryptServiceContext
 import net.mamoe.mirai.internal.utils.io.encryptAndWrite
+import net.mamoe.mirai.internal.utils.io.serialization.writeProtoBuf
 import net.mamoe.mirai.internal.utils.io.writeHex
 import net.mamoe.mirai.internal.utils.io.writeIntLVPacket
 import net.mamoe.mirai.utils.*
@@ -130,15 +131,66 @@ internal fun <R : Packet?> buildRawUniPacket(
                 writeInt(it.length + 4)
                 writeText(it)
             }
+            val encryptWorker = EncryptService.instance
+            val bodyBytes = buildPacket { body(sequenceId) }.readBytes()
+            val signDataPacket = if (encryptWorker != null) {
 
+                val signResult = encryptWorker.qSecurityGetSign(
+                    EncryptServiceContext(client.uin, buildTypeSafeMap {
+                        set(EncryptServiceContext.KEY_APP_QUA, "V1_AND_SQ_8.9.58_4106_YYB_D") // 8.9.58
+                        set(EncryptServiceContext.KEY_CHANNEL_PROXY, createChannelProxy(client.bot))
+                        set(EncryptServiceContext.KEY_DEVICE_INFO, client.device)
+                        set(EncryptServiceContext.KEY_QIMEI36, client.qimei36 ?: "")
+                    }),
+                    sequenceId,
+                    commandName,
+                    bodyBytes
+                )
+                if (signResult != null)
+                    buildPacket {
+                        writeProtoBuf(
+                            SSOReserveField.ReserveFields.serializer(),
+                            SSOReserveField.ReserveFields(
+                                flag = 0,
+                                qimei = client.qimei16?.toByteArray() ?: EMPTY_BYTE_ARRAY,
+                                newconnFlag = 0,
+                                uid = client.uin.toString(),
+                                imsi = 0,
+                                networkType = 1,
+                                ipStackType = 1,
+                                messageType = 0,
+                                secInfo = SSOReserveField.SsoSecureInfo(
+                                    secSig = signResult.sign,
+                                    secDeviceToken = signResult.token,
+                                    secExtra = signResult.extra
+                                ),
+                                ssoIpOrigin = 0,
+                            )
+                        )
+                    } else BRP_STUB
+            } else BRP_STUB
+
+            if (signDataPacket != BRP_STUB && (extraData != BRP_STUB && extraData.remaining != 0L)) {
+                throw IllegalStateException("$commandName cmd needs sign but has extraData!")
+            }
             if (encryptMethod === PacketEncryptType.NoEncrypt) {
-                writeUniPacket(commandName, client.outgoingPacketSessionId, extraData) {
-                    body(sequenceId)
+                writeUniPacket(
+                    commandName,
+                    client.outgoingPacketSessionId,
+                    signDataPacket,
+                    (client.qimei16?.encodeToByteArray() ?: EMPTY_BYTE_ARRAY)
+                ) {
+                    writeFully(bodyBytes)
                 }
             } else {
                 encryptAndWrite(key) {
-                    writeUniPacket(commandName, client.outgoingPacketSessionId, extraData) {
-                        body(sequenceId)
+                    writeUniPacket(
+                        commandName,
+                        client.outgoingPacketSessionId,
+                        signDataPacket,
+                        (client.qimei16?.encodeToByteArray() ?: EMPTY_BYTE_ARRAY)
+                    ) {
+                        writeFully(bodyBytes)
                     }
                 }
             }
@@ -183,8 +235,9 @@ internal inline fun <R : Packet?> IncomingPacketFactory<R>.buildResponseUniPacke
 
 private inline fun BytePacketBuilder.writeUniPacket(
     commandName: String,
-    unknownData: ByteArray,
+    outgoingPacketSessionId: ByteArray,
     extraData: ByteReadPacket = BRP_STUB,
+    qimei16: ByteArray = EMPTY_BYTE_ARRAY,
     crossinline body: BytePacketBuilder.() -> Unit
 ) {
     writeIntLVPacket(lengthOffset = { it + 4 }) {
@@ -193,8 +246,8 @@ private inline fun BytePacketBuilder.writeUniPacket(
             writeText(it)
         }
 
-        writeInt(4 + 4)
-        writeFully(unknownData) //  02 B0 5B 8B
+        writeInt(outgoingPacketSessionId.size + 4)
+        writeFully(outgoingPacketSessionId) //  02 B0 5B 8B
 
         if (extraData === BRP_STUB) {
             writeInt(0x04)
@@ -202,6 +255,9 @@ private inline fun BytePacketBuilder.writeUniPacket(
             writeInt((extraData.remaining + 4).toInt())
             writePacket(extraData)
         }
+
+        writeInt(qimei16.size + 4)
+        writeFully(qimei16)
     }
 
     // body