tags: 3DES Android Operating mode Fill mode
2019.5.9 update instructions:
Attention! ! ! ! ! If the key is incorrect, an exception will be reported when decrypting: pad block corrupted
At first I thought that my code was incorrect, I still found a half-day data, and finally found that the key is wrong.
Recently, a project needs to use 3DES encryption and decryption. There are many articles and codes on the Internet for 3DES encryption and decryption. However, because 3DES encryption and decryption need to determine the encryption mode and the filling method, most of the online are used by default. The result of your encryption and decryption may not be consistent with the server.
The first is the encryption process. Here we define the string to be encrypted as data, the key as key (here we use kotlin), and the other thing to note is that the string When converting to byte[], we need to maintain the unity of coding. Here we use utf-8 uniformly.
val data = "123456"
val key = "123"
In 3DES encryption and decryption, if the length of the key is less than 24, we need to make up 24 bits and add 0 to the back.
val bytes = key.toByteArray()
val keyBytes = ByteArray(24)
if (bytes.size < 24) System.arraycopy(bytes, 0, keyBytes, 0, bytes.size)
Then we need to create an encryption and decryption engine
//The DESede here indicates 3DES encryption, and the ECB is the encryption mode. In addition to the ECB, there are CBC CTR OFB CFB, etc.
//PKCS5Padding indicates padding mode Other padding modes are NoPadding, PKCS7Padding
//The suggestions here are filled in according to ECB and PKCS5Padding. How to use other encryption modes and padding modes, I haven't figured it out yet.
val cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding")
The next step is to get the byte[] after encryption.
val secretKey = SecretKeyFactory.getInstance("DESede").generateSecret(DESedeKeySpec(keyBytes))
//This means that we are in encryption mode.
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
//This is the byte[] after the final encryption.
val doFinal = cipher.doFinal(data.toByteArray())
In general, we will convert byte[] to a string after encryption, but we can't convert it directly here, we have to convert it to Base64.
/ / Again, here you need to pay attention to the coding problem
val content = String(Base64.getEncoder().encode(doFinal), Charset.forName("utf-8"))
The encryption process ends here. The decryption process is almost the same as encryption. Basically, the whole process is reversed.
val data = "YQZ2+68kOck="
val key = "123"
val bytes = key.toByteArray()
val keyBytes = ByteArray(24)
if (bytes.size < 24) System.arraycopy(bytes, 0, keyBytes, 0, bytes.size)
val cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding")
val secretKey = SecretKeyFactory.getInstance("DESede").generateSecret(DESedeKeySpec(keyBytes))
cipher.init(Cipher.DECRYPT_MODE, secretKey)
val decode = Base64.getDecoder().decode(data.toByteArray())
val final = cipher.doFinal(decode)
val content = String(final, Charset.forName("utf-8"))
Finally, paste a complete code for encryption and decryption.
import android.os.Build
import android.support.annotation.RequiresApi
import java.nio.charset.Charset
import java.util.*
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.DESedeKeySpec
class SecretUtil {
companion object {
private const val Algorithm = "DESede"
private const val Transformation = "DESede/ECB/PKCS5Padding"
@RequiresApi(Build.VERSION_CODES.O)
fun decrypt3DES(data: String, key: String): String {
val bytes = key.toByteArray()
val keyBytes = ByteArray(24)
if (bytes.size < 24) System.arraycopy(bytes, 0, keyBytes, 0, bytes.size)
val cipher = Cipher.getInstance(Transformation)
val secretKey = SecretKeyFactory.getInstance(Algorithm).generateSecret(DESedeKeySpec(keyBytes))
cipher.init(Cipher.DECRYPT_MODE, secretKey)
val decode = Base64.getDecoder().decode(data.toByteArray())
val final = cipher.doFinal(decode)
return String(final, Charset.forName("utf-8"))
}
@RequiresApi(Build.VERSION_CODES.O)
fun encrypt3DES(data: String, key: String): String {
val bytes = key.toByteArray()
val keyBytes = ByteArray(24)
if (bytes.size < 24) System.arraycopy(bytes, 0, keyBytes, 0, bytes.size)
val cipher = Cipher.getInstance(Transformation)
val secretKey = SecretKeyFactory.getInstance(Algorithm).generateSecret(DESedeKeySpec(keyBytes))
cipher.init(Cipher.ENCRYPT_MODE, secretKey)
val doFinal = cipher.doFinal(data.toByteArray())
return String(Base64.getEncoder().encode(doFinal), Charset.forName("utf-8"))
}
}
}
encryption Encryption is divided into symmetric encryption and asymmetric encryption. Symmetric encryption algorithm, both sides of the information receiving need to know the key and the encryption an...
3EDS-CBC encryption and decryption 3DES-CDC encryption and decryption 3DES-CDC encryption and decryption Recently, there is a need to write a 3DES-CBC encryption and decryption method, check a lot of ...
Talking about data security When you use online banking, are you worried that your bank card will be stolen? When you and your friends use QQ to chat, are you worried that your privacy will be ...
Client uses CryptoJS encryption and decryption transfer encryption Decrypt...
3DES encryption and decryption Base64 and Hex Both Base64 and Hex belong to the encoding form, Hex is also called Base16. In the encryption and decryption process of 3DES, two encoding forms need to b...
It is tested that the encryption and decryption of this online tool is completely consistent with the interface provided by China Construction Bank. Creation is not easy, if you need the source code, ...
PHP server, Java server, Android, iOS development compatible 3DES encryption decryption, php java(android) Ojbective-C(ios) Transfer from:...
encryption Decrypt Note: Be sure to decrypt with Base64, I have been garbled because I didn't use Base64....