Progress AES Decryption NoPadding

Hi everybody, does anyone knows how to decrypt with 4GL without padding?, i have been trying to do it but i fail everytime, i managed to do it with java but i don't know how to replicate the code in 4GL

4GL Implementation:

DEFINE VARIABLE TextToDecrypt    AS CHARACTER NO-UNDO.
DEFINE VARIABLE EncryptionAlgor  AS CHARACTER NO-UNDO.
DEFINE VARIABLE EncryptionKeyHex AS CHARACTER NO-UNDO.
DEFINE VARIABLE EncryptionIVHex  AS CHARACTER NO-UNDO.
DEFINE VARIABLE cDecryptedText   AS CHARACTER NO-UNDO.

ASSIGN TextToDecrypt    = "10fe7bb47f366aee841e91dbccc6e66fb08ca3c01253d92039f657916ecb4c79e35325765ae9c7f5297643e7c73dfc463bddce9c11f9b24723d457649f57b10b5fa98bccadd62b58da7c90fe21ef1d2eacc713f73a0f334988aaca10352c068bf33a77c4ae6744725f6dc52a067bdba12ea4034796336e17d71ce67b24a7b586"
       EncryptionAlgor  = "AES_CBC_128"
       EncryptionKeyHex = "0123456789ABCDEFFEDCBA9876543210"
       EncryptionIVHex  = "00000000000000000000000000000000"
       cDecryptedText   = "".

DEFINE VARIABLE BinaryData AS RAW NO-UNDO.
PUT-STRING(BinaryData, 1) = TextToDecrypt.

DEBUGGER:INITIATE().
DEBUGGER:SET-BREAK().

ASSIGN SECURITY-POLICY:SYMMETRIC-ENCRYPTION-ALGORITHM = EncryptionAlgor
       SECURITY-POLICY:SYMMETRIC-ENCRYPTION-KEY       = HEX-DECODE(EncryptionKeyHex)
       SECURITY-POLICY:SYMMETRIC-ENCRYPTION-IV        = HEX-DECODE(EncryptionIVHex)
       cDecryptedText                                 = BASE64-ENCODE(DECRYPT(BinaryData))
       /*cDecryptedText                                 = BASE64-ENCODE(DECRYPT(HEX-DECODE(TextToDecrypt)))*/
       .

Java Implementation:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import static java.lang.Character.digit;

public class AES {

	public static void main(String[] args) throws Exception {
		
		String Key     = "0123456789ABCDEFFEDCBA9876543210";
		String IV      = "00000000000000000000000000000000";
		String HexText = "10fe7bb47f366aee841e91dbccc6e66fb08ca3c01253d92039f657916ecb4c79e35325765ae9c7f5297643e7c73dfc463bddce9c11f9b24723d457649f57b10b5fa98bccadd62b58da7c90fe21ef1d2eacc713f73a0f334988aaca10352c068bf33a77c4ae6744725f6dc52a067bdba12ea4034796336e17d71ce67b24a7b586";
		
		try 
		{
			byte[] decryptByte = null;
			decryptByte = Decrypt(Key, IV, HexText);
			
			String hexString = ByteToHex(decryptByte);
			System.out.println(hexString);		// Imprimir texto en hexadecimal
		    //StringBuilder decryptedString = HexToString(hexString);
		    //System.out.println(decryptedString);
		} catch (Exception e) { 
			e.printStackTrace();
		}
		
	}
	
	public static byte[] Decrypt(String Key, String IV, String hexText) throws Exception {
	    String algorithm = "AES";
	    String mode = "CBC";
	    String padding = "NoPadding";
	    
	    byte[] ciphertextBytes = StringToByte(hexText);
	    byte[] keyBytes = StringToByte(Key);
	    byte[] ivParamSpecTMP = StringToByte(IV);
	    
	    IvParameterSpec ivParameterSpec = new IvParameterSpec(ivParamSpecTMP);
	    SecretKey aesKey = new SecretKeySpec(keyBytes, "AES");

	    Cipher cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + padding);
	    cipher.init(Cipher.DECRYPT_MODE, aesKey, ivParameterSpec);

	    byte[] result = cipher.doFinal(ciphertextBytes);
	    return result;
	}
	
	//convert ByteArray to Hex String
	public static String ByteToHex(byte[] byteArray) {
	    StringBuilder sb = new StringBuilder();
	    for (byte b : byteArray)
	    {
	        sb.append(String.format("%02X", b));
	    }
	    return sb.toString();
	}

	//convert String to ByteArray
	private static byte[] StringToByte(String input) {
	    int length = input.length();
	    byte[] output = new byte[length / 2];

	    for (int i = 0; i < length; i += 2) {
	        output[i / 2] = (byte) ((digit(input.charAt(i), 16) << 4) | digit(input.charAt(i+1), 16));
	    }
	    return output;
	}
	
	//changes a hex string into plain text
	public static StringBuilder HexToString(String hex) throws Exception {
	    StringBuilder output = new StringBuilder();
	    for (int i = 0; i < hex.length(); i+=2) {
	        String str = hex.substring(i, i+2);
	        output.append((char)Integer.parseInt(str, 16));
	    }
	    return output;
	}
}


Perl Implementation

use Crypt::CBC;
use Crypt::Cipher::AES;
 
my $text = '10fe7bb47f366aee841e91dbccc6e66fb08ca3c01253d92039f657916ecb4c79e35325765ae9c7f5297643e7c73dfc463bddce9c11f9b24723d457649f57b10b5fa98bccadd62b58da7c90fe21ef1d2eacc713f73a0f334988aaca10352c068bf33a77c4ae6744725f6dc52a067bdba12ea4034796336e17d71ce67b24a7b586';
my $key = '0123456789ABCDEFFEDCBA9876543210'; 
my $iv = '00000000000000000000000000000000';

my $strText = pack("H*", $text);
my $strKey = pack("H*", $key);
my $strIV  = pack("H*", $iv);

my $cbc = Crypt::CBC->new( 
	-cipher=>'Cipher::AES', 
	-key=>$strKey, 
	-iv=>$strIV,
	-padding => 'none',
	-header => 'none',
	-literal_key => 1,
	-keysize => 16
	);
	
my $ciphertext = $cbc->decrypt($strText);
print $ciphertext;

Decrypted text:

{"tran":{"estado":"ERROR","mensaje":"Duplicateentry'140812-153820-777-7777777777777777-123456783821'forkey'PRIMARY'"}}     

Online Tools
http://aes.online-domain-tools.com/

If anyone knows how to solve this issue i would be very thankfull

Thanks in advance.

Att: William Martinez


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

You can also use .Net

You can also use .Net libraries in place of the Openedge SECURITY-POLICY methods. Code below in case it helps someone else, ofcourse, the password etc would need to be more secure!

The basis of this was taken from http://stackoverflow.com/questions/17113113/interop-encryption-decryptio...

Using System.Security.Cryptography.* from Assembly.
Using System.Text.*                  from Assembly.
Using System.Convert                 from Assembly.
Using System.Buffer                  from Assembly.

def var mv_sPassword    as char init "RandomString".
def var mv_sSalt        as char init "12345678".
def var mv_sIV          as char init "1234567812345678".
def var mv_iIterations  as int  init 1000.
def var mv_sCipherMode  as char init "CBC".
def var mv_sPaddingMode as char init "PKCS7".

Function GetCryptoTransform ICryptoTransform (csp as AesCryptoServiceProvider, ip_bEncrypting as log): 
    
  def var spec as Rfc2898DeriveBytes.    
  def var aSalt as "System.Byte[]".
  def var aPass as "System.Byte[]".
  
  Case mv_sPaddingMode:    
    When "None" then csp:Padding = PaddingMode:None.
    When "Zeros" then csp:Padding = PaddingMode:Zeros.
    When "ANSIX923" then csp:Padding = PaddingMode:ANSIX923.
    When "ISO10126" then csp:Padding = PaddingMode:ISO10126.
    otherwise csp:Padding = PaddingMode:PKCS7.
  end.
  
  case mv_sCipherMode:
    When "ECB" then csp:Mode = CipherMode:ECB.
    When "OFB" then csp:Mode = CipherMode:OFB.
    When "CFB" then csp:Mode = CipherMode:CFB.
    When "CTS" then csp:Mode = CipherMode:CTS.
    Otherwise csp:Mode = CipherMode:CBC.
  End.
  
  aSalt = Encoding:UTF8:GetBytes(mv_sSalt).
  aPass = Encoding:UTF8:GetBytes(mv_sPassword).
  
  spec = new Rfc2898DeriveBytes(aPass, aSalt, mv_iIterations).
  
  csp:IV = Encoding:UTF8:GetBytes(mv_sIV).
  csp:Key = spec:GetBytes(16).
  
  if (ip_bEncrypting) then return csp:CreateEncryptor().
  
  delete object spec.
  delete object aSalt.
  delete object aPass.
  
  return csp:CreateDecryptor().

End Procedure.

Procedure SetPassword:
  def input param ip_sValue as char no-undo.
  mv_sPassword = ip_sValue.
End Procedure.

Procedure SetSalt:
  def input param ip_sValue as char no-undo.
  mv_sSalt = ip_sValue.
End Procedure.

Procedure SetIV:
  def input param ip_sValue as char no-undo.
  mv_sIV = ip_sValue.
End Procedure.

Procedure SetIterations:
  def input param ip_iValue as int no-undo.
  mv_iIterations = ip_iValue.
End Procedure.

Procedure SetCipherMode:
  def input param ip_sValue as char no-undo.
  mv_sCipherMode = ip_sValue.
End Procedure.

Procedure SetPaddingMode:
  def input param ip_sValue as char no-undo.
  mv_sPaddingMode = ip_sValue.
End Procedure.

Procedure DecryptText:
  def input param ip_sStringIn as longchar no-undo.
  def output param ip_sStringOut as longchar no-undo.
  
  def var csp             as AesCryptoServiceProvider.
  def var CryptoTransform as ICryptoTransform.
  def var strBytes        as "System.Byte[]".
  def var CryptoOutput    as "System.Byte[]".       
  def var iLen            as int no-undo.

  if ip_sStringIn > "" then. else return.
  
  csp = new AesCryptoServiceProvider().
  CryptoTransform = GetCryptoTransform(csp, false).
  
  strBytes = Convert:FromBase64String(ip_sStringIn).
  
  iLen = Buffer:ByteLength(strBytes).
  
  CryptoOutput = CryptoTransform:TransformFinalBlock(strBytes, 0, iLen).

  ip_sStringOut = Encoding:UTF8:GetString(CryptoOutput).
    
  delete object CryptoTransform.
  delete object csp.
  delete object strBytes.
  delete object CryptoOutput.
  
End Function.

Procedure EncryptText:
  def input param ip_sStringIn as longchar no-undo.
  def output param ip_sStringOut as longchar no-undo.
   
  def var csp             as AesCryptoServiceProvider.
  def var CryptoTransform as ICryptoTransform.
  def var strBytes        as "System.Byte[]".
  def var CryptoOutput    as "System.Byte[]".
  def var iLen            as int no-undo.

  if ip_sStringIn > "" then. else return.
  
  csp = new AesCryptoServiceProvider().
  CryptoTransform = GetCryptoTransform(csp, true).
  
  strBytes = Encoding:UTF8:GetBytes(ip_sStringIn).
  iLen =  Buffer:ByteLength(strBytes).

  CryptoOutput = CryptoTransform:TransformFinalBlock(strBytes, 0, iLen).
  
  ip_sStringOut = Convert:ToBase64String(CryptoOutput).    
  
    
  delete object CryptoTransform.
  delete object csp.
  delete object strBytes.
  delete object CryptoOutput.
  
End Function.

Procedure Test private:
  def var sText as char.
  def var sEncText as char.
  def var sDecText as char.
  
  sText = "String To Encrypt".
  
  run EncryptText(sText, output sEncText).
  run DecryptText(sEncText, output sDecText).
  
  message "Text: " sText "~n~nEncText: " sEncText "~n~nDecryptText: " sDecText.
end.


Run Test.


AttachmentSize
crypto.p4.52 KB

Thanks

Thanks a lot for the code, it really helped me out¡¡