我在Kotlin中创建了一个客户端 - 服务器聊天应用程序。客户端是一个Android客户端,并通过套接字与服务器通信。 我有一个带有不同构造函数的MessageObject来生成不同类型的Message。
MessageObject.kt
package message
import com.cyens.chat.securechat.message.Type
import com.cyens.chat.securechat.user.User
import java.io.Serializable
import java.security.PublicKey
import java.text.SimpleDateFormat
import java.util.*
class MessageObject(var type: Type) : Serializable {
val created = SimpleDateFormat("HH:mm").format(Date())
var message: String? = null
private set
var receiver: String? = null
private set
var username: String? = null
private set
var password: String? = null
private set
var friend: User? = null
private set
var friends: ArrayList<User>? = null
private set
var publicKey: PublicKey? = null
private set
var chats: ArrayList<MessageObject>? = null
private set
var version: String? = null
private set
var key: ByteArray? = null
private set
var read: Boolean = false
var answer: Int = 0
companion object {
private const val serialVersionUID: Long = 1
}
constructor(type: Type, publicKey: PublicKey) : this(type) {
this.publicKey = publicKey
}
constructor(type: Type, key: ByteArray) : this(type){
this.key = key
}
constructor(type: Type, username: String, password: String, version: String) : this(type) {
this.username = username
this.password = password
this.version = version
}
constructor(type: Type, message: String, receiver: String) : this(type) {
this.message = message
this.receiver = receiver
}
constructor(type: Type, answer: Int) : this(type) {
this.answer = answer
}
constructor(type: Type, s: String) : this(type) {
this.message = s
}
constructor(type: Type, user: User) : this(type){
this.friend = user
}
constructor(type: Type, list: ArrayList<Any>) : this(type) {
if (type == Type.CHATS)
this.chats = list as ArrayList<MessageObject>
else
this.friends = list as ArrayList<User>
}
}
发送的前两条消息未加密,之后每个MessageObject都被加密。
发送消息的功能:
fun send(messageObject: MessageObject){
async {
val secretKey = Keys.secretKey
if (secretKey == null){
outputStream.writeObject(messageObject)
}
else {
System.out.println("SecretKey not null")
AES256.encrypt(messageObject, outputStream)
}
outputStream.flush()
}
}
当我现在接收服务器上的消息时,我正在检查对象是否已加密:
messageObject = if (inputStream.readObject() is MessageObject) {
inputStream.readObject() as MessageObject
} else
RSACipher.decrypt(inputStream, Keys.privateKey)
在inputStream.readObject()上抛出ClassNotFoundException (我甚至没有使用conscrypt,所以这是从哪里来的?) Stacktrace:
java.lang.ClassNotFoundException: com.android.org.conscrypt.OpenSSLRSAPublicKey
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:686)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1866)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1749)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2040)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1571)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2285)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2209)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2067)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1571)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at server.ClientThread.run(ClientThread.kt:61)
我的加密和解密方法
fun encrypt(message: MessageObject, outStream: OutputStream, publicKey: PublicKey) {
// Create cipher
val cipher = Cipher.getInstance(transformation)
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
val sealedObject = SealedObject(message, cipher)
// Wrap the output stream
val cos = CipherOutputStream(outStream, cipher)
val outputStream = ObjectOutputStream(cos)
outputStream.writeObject(sealedObject)
outputStream.close()
}
fun decrypt(inStream: InputStream, privateKey: PrivateKey): MessageObject {
val cipher = Cipher.getInstance(transformation)
cipher.init(Cipher.DECRYPT_MODE, privateKey)
val cipherInputStream = CipherInputStream(inStream, cipher)
val inputStream = ObjectInputStream(cipherInputStream)
val sealedObject: SealedObject
sealedObject = inputStream.readObject() as SealedObject
return sealedObject.getObject(cipher) as MessageObject
}
感谢您的帮助,对不起我的英语。 Ludtwigk