Я создаю клиент-серверное приложение чата в Котлине.Клиент является клиентом Android и взаимодействует с сервером через сокеты.У меня есть MessageObject с разными конструкторами для создания разных типов сообщений.
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)
ClassNotFoundException выбрасывается в inputStream.readObject () (я даже не использую concerypt, так откуда же это происходит?) 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