Search code examples
pythonscalaaespycryptocbc-mode

How to use AES Encryption and Decryption from Scala to Python


I have a code in scala where I have my encryption and decryption code, It works fine and the code is:

import java.util.Base64
import javax.crypto.Cipher
import javax.crypto.spec.{IvParameterSpec, SecretKeySpec}
class Encryption {
val key = "enIntVecTest2020"
val initVector = "encryptionIntVec"

def encrypt(text: String): String = {

val  iv = new IvParameterSpec(initVector.getBytes("UTF-8"))
val  skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES")

val  cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv)

val  encrypted = cipher.doFinal(text.getBytes())
return Base64.getEncoder().encodeToString(encrypted)
}

def decrypt(text:String) :String={
val  iv = new IvParameterSpec(initVector.getBytes("UTF-8"))
val  skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES")

val  cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv)
val  original = cipher.doFinal(Base64.getDecoder.decode(text))

new String(original)
}
}

val encryptobj = new Encryption()
val pwd = "#test@12345"
val result =encryptobj.encrypt(pwd)

pwd: String = #test@12345
result: String = lHhq1OzMSYnj+0XxiNzKhQ==

val pwd1  = encryptobj.decrypt(result)
println(pwd1)

pwd1: String = #test@12345
#test@12345

I tried in Python to achieve the same but does not give the expected encryption result, here is my code(I took the help of other similar answers):

from hashlib import sha256
import base64
from Crypto import Random
from Crypto.Cipher import AES

BS = 16
pad = lambda s: bytes(s + (BS - len(s) % BS) * chr(BS - len(s) % BS), 'utf-8')
unpad = lambda s : s[0:-ord(s[-1:])]

class AESCipher:

    def __init__( self, key ):
        self.key = bytes(key, 'utf-8')

    def encrypt( self, raw ):
        raw = pad(raw)
        iv = "encryptionIntVec".encode('utf-8')
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return base64.b64encode( iv + cipher.encrypt( raw ) )

    def decrypt( self, enc ):
        enc = base64.b64decode(enc)
        iv = enc[:16]
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return unpad(cipher.decrypt( enc[16:] )).decode('utf8')

    cipher = AESCipher('enIntVecTest2020')
    encrypted = cipher.encrypt('#test@12345')
    decrypted = cipher.decrypt(encrypted)
    
    print(encrypted)

b'ZW5jcnlwdGlvbkludFZlY5R4atTszEmJ4/tF8YjcyoU='

As you can see both the encryption is not right, I don't know where I am doing wrong. Please help in achieving the same encrypting result in python as showing in scala, I would be much thankful.


Solution

  • Thanks to @Topaco answer and after some search it worked.

    import base64
    from Crypto.Cipher import AES
    
    BS = 16
    pad = lambda s: bytes(s + (BS - len(s) % BS) * chr(BS - len(s) % BS), 'utf-8')
    unpad = lambda s : s[0:-ord(s[-1:])]
    class AESCipher:
    
        def __init__( self, key ):
            self.key = bytes(key, 'utf-8')
    
        def encrypt( self, raw ):
            raw = pad(raw)
            iv = "encryptionIntVec".encode('utf-8')
            cipher = AES.new(self.key, AES.MODE_CBC, iv )
            return base64.b64encode(cipher.encrypt( raw ) )
        def decrypt( self, enc ):
            iv = "encryptionIntVec".encode('utf-8')
            enc = base64.b64decode(enc)
            cipher = AES.new(self.key, AES.MODE_CBC, iv )
            return unpad(cipher.decrypt( enc )).decode('utf8')
    cipher = AESCipher('enIntVecTest2020')
    encrypted = cipher.encrypt('#test@12345')
    print(encrypted.decode('utf-8'))
    -> lHhq1OzMSYnj+0XxiNzKhQ==
    decrypted = cipher.decrypt(encrypted)
    print(decrypted)
    -> #test@12345