I would like to know what could be the problem in the code below.
I'm part of a university team developing solutions in Bada using NFC and server connections. To encrypt the comunication we have though use Aes encryption, but I'm stopped in the following error:
String
ReadForm::aesEncryp(Osp::Base::String ip, Osp::Base::String mac, Osp::Base::String msg)
{
AppLog("<<<<<<<<<<<<<< aesEncrypt Start >>>>>>>>>>>>>>>>>>>>>>>>>");
Osp::Text::Utf8Encoding utf8Enc;
Osp::Text::AsciiEncoding* dato = new Osp::Text::AsciiEncoding();
result r;
//msg
ByteBuffer* pbuffer=dato->GetBytesN(msg);
AppLog("asigno mensaje: %ls", msg.GetPointer());
int messageLen; // msg.GetLength()*8;
r=dato->GetByteCount(msg,messageLen);
AppLog("obtiene bytes: %s", GetErrorMessage(r));
byte message[messageLen+1];
r=pbuffer->GetArray(message,0,messageLen);
AppLog("Establece mensaje en array: %s", GetErrorMessage(r));
// KEY: 16 bytes
int secretKeyLen;
ip="xxxxxxxxxxxxx";
r=dato->GetByteCount(ip,secretKeyLen);
AppLog("obtiene bytes: %s", GetErrorMessage(r));
pbuffer=null;
pbuffer=dato->GetBytesN(ip);
byte secretKey[secretKeyLen+1];
r=pbuffer->GetArray(secretKey,0,secretKeyLen);
AppLog("Establece key en array: %s", GetErrorMessage(r));
// IV: 16 bytes
int ivectorLen;
String ivM="xxxxxxxxxxxx";
pbuffer=null;
pbuffer=dato->GetBytesN(ivM);
r=dato->GetByteCount(ivM,ivectorLen);
AppLog("obtiene bytes: %s", GetErrorMessage(r));
byte ivector[ivectorLen+1];
r=pbuffer->GetArray(ivector,0,ivectorLen);
AppLog("Establece vector en array: %s", GetErrorMessage(r));
String transformation;
ISymmetricCipher *pCipher = null;
SecretKeyGenerator *pKeyGen = null;
ISecretKey *pKey = null;
ByteBuffer input;
ByteBuffer *pOutput = null;
ByteBuffer keyBytes;
ByteBuffer iv;
//msg
input.Construct(messageLen+1);
input.SetArray(message, 0, messageLen);
input.Flip();
//key
keyBytes.Construct(secretKeyLen+1);
keyBytes.SetArray(secretKey, 0, 16);
keyBytes.Flip();
//vector
iv.Construct(ivectorLen);
iv.SetArray(ivector, 0, ivectorLen);
iv.Flip();
//cifrado
pCipher = new AesCipher();
transformation = "CBC/128/NOPADDING";
pCipher->Construct(transformation,CIPHER_ENCRYPT);
AppLog("AesCipher construct:%s", GetErrorMessage(r));
pKeyGen = new SecretKeyGenerator();
pKeyGen->Construct(keyBytes);
pKey = pKeyGen->GenerateKeyN();
if (pKey==null){
r = GetLastResult();
AppLog("Generate -> pKey Esnulo: %s",GetErrorMessage(r));
}
r=pCipher->SetKey(*pKey);
AppLog("AesCipher setKey:%s", GetErrorMessage(r));
r=pCipher->SetInitialVector(iv);
AppLog("AesCipher setInitialVector:%s", GetErrorMessage(r));
//encripto
pOutput = pCipher->EncryptN(input); <---------- returns null why!!!!!!!!!!!
if (pOutput==null){
r = GetLastResult();
AppLog("pOutput nulo: %s",GetErrorMessage(r));
}
AppLog("Encriptado");
//preparo para devolver
Osp::Text::AsciiEncoding* as = new Osp::Text::AsciiEncoding();
as->GetString(*pOutput,ResultadoAes);
AppLog("aes= %ls", ResultadoAes.GetPointer() );
AppLog("<<<<<<<<<<<<<< aesEncrypt Finish >>>>>>>>>>>>>>>>>>>>>>>>>");
return ResultadoAes;
}
The input and keylength should be multiple of 16.
What i understand from your code, your message length is multiple of 8.
Also since you are using NOPADDING, when you are constructing bytebuffer for input and keybytes, please make sure that they are exactly multiple of 16.
Finally, incase you are still getting problem, please post what error message you are getting from
r = GetLastResult()
Related
Suppose the plaintext is a string, and I map the plaintext to the group using setFromHash function before I can perform the encryption operation, and the final decryption is only the hash of the plaintext, not the plaintext, how can I decrypt the plaintext or perform the bilinear operation without mapping the plaintext to the group? (Can this be achieved without using symmetric encryption)
setup(pairingParametersFileName, pkFileName, mskFileName);
keygen(pairingParametersFileName, userAttList, pkFileName, mskFileName, skFileName);
String msg = "dasddwhqoiuhdaiosnioacjijdqwi0jdaposdjiasojcbndusivbuiweshfsaoindoai";
//byte[] sha1Result = sha1(msg);
//Element message = PairingFactory.getPairing(pairingParametersFileName).getGT().newRandomElement().getImmutable();
//Element message = PairingFactory.getPairing(pairingParametersFileName).getGT().newElement().setFromHash(sha1Result, 0, sha1Result.length).getImmutable();
Element message = PairingFactory.getPairing(pairingParametersFileName).getGT().newElement().setFromHash(msg, 0, msg.length).getImmutable();
System.out.println("plaintext:" + msg);
encrypt(pairingParametersFileName, message, accessTree, pkFileName, ctFileName);
Element res = decrypt(pairingParametersFileName, accessTree, ctFileName, skFileName);
System.out.println("decrypt:" + res);
if (message.isEqual(res)) {
System.out.println("successful!");
}
Pairing bp = PairingFactory.getPairing(pairingParametersFileName);
Properties pkProp = loadPropFromFile(pkFileName);
String gString = pkProp.getProperty("g");
Element g = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(gString)).getImmutable();
String g_betaString = pkProp.getProperty("g_beta");
Element g_beta = bp.getG1().newElementFromBytes(Base64.getDecoder().decode(g_betaString)).getImmutable();
String egg_alphaString = pkProp.getProperty("egg_alpha");
Element egg_alpha = bp.getGT().newElementFromBytes(Base64.getDecoder().decode(egg_alphaString)).getImmutable();
Properties ctProp = new Properties();
//compute CT=M *e(g,g)^(alpha s)
Element s = bp.getZr().newRandomElement().getImmutable();
Element CT = message.duplicate().mul(egg_alpha.powZn(s)).getImmutable();
Element C = g_beta.powZn(s).getImmutable();
this is not achievable, pairing-based CP-ABE, if encrypted, requires plaintext in the G_T group, but there is no good way to encode a message to the G_T group
My two functions:
public static void encrypt(IFormFile uploadFile)
{
ICryptoTransform transform = _crypt_provider.CreateEncryptor();
//Extraer los datos del csv en un string
string text;
using (var reader = new StreamReader(uploadFile.OpenReadStream()))//, Encoding.UTF8
{
// lectura del contenido del archivo
text = reader.ReadToEnd();
}
byte[] encrypted_bytes = transform.TransformFinalBlock(Encoding.UTF8.GetBytes(text) , 0, text.Length);
string textoEncrypted = Convert.ToBase64String(encrypted_bytes);
//string textoEncrypted = Encoding.UTF8.GetString(encrypted_bytes);
Debug.WriteLine($"El texto ingresado = {text} \nEl texto encriptado = {textoEncrypted}");
File.WriteAllText(uploadFile.FileName, textoEncrypted);
}
public static string decrypt(IFormFile uploadFile)
{
string text;
using (var reader = new StreamReader(uploadFile.OpenReadStream()))//, Encoding.GetEncoding("iso-8859-1")
{
// lectura del contenido del archivo
text = reader.ReadToEnd();
}
ICryptoTransform transform = _crypt_provider.CreateDecryptor();
byte[] encrypted_bytes = Convert.FromBase64String(text);
//byte[] encrypted_bytes = Encoding.UTF8.GetBytes(text);
byte[] dencrypted_bytes = transform.TransformFinalBlock(encrypted_bytes, 0, encrypted_bytes.Length);
string textoDesencriptado = Encoding.UTF8.GetString(dencrypted_bytes);
//File.WriteAllText(uploadFile.FileName, textoDesencriptado);
Debug.WriteLine($"El texto ingresado = {text} \nEl texto desencriptado = {textoDesencriptado}");
return textoDesencriptado;
}
This is my .csv input:
50001,José,,Peréz,Gonzáles,1998-07-06
50002,Miguel,,Hermandez,Hermandez,1998-07-06
50003,Raúl,,Ramirez,Gutierrez,1998-07-06
50004,Laura2,Araceli,Ordoñez,Alcazar,1998-07-06
50005,Yazmin2,,Herrera,García,1998-07-06
50007,Prb2, Prb,Prb3,Herreras,1998-07-06
And the output:
50001,José,,Peréz,Gonzáles,1998-07-06
50002,Miguel,,Hermandez,Hermandez,1998-07-06
50003,Raúl,,Ramirez,Gutierrez,1998-07-06
50004,Laura2,Araceli,Ordoñez,Alcazar,1998-07-06
50005,Yazmin2,,Herrera,García,1998-07-06
50007,Prb2, Prb,Prb3,Herreras,1998
Missing -07-06 in the 50007.
I'm using UTF-8 because I need to encrypt special characters.
General speaking if the decrypt fails you read nothing.
So the error must be on the reading / encrypting.
Change this lines on the text to encrypt - not give the text.Length, but the array length.
byte[] toEncryptArray = ASCIIEncoding.BigEndianUnicode.GetBytes(toEncrypt);
byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
I'm using .tt scripting in VS 2017(SSDT 2017) in the DB project. We create staging tables structures manually and then the T4 script generates final destination tables based on the staging table structure.
I have this code to get columns and their data types to create my final destination tables but it looks if one of the fields is defined as varchar(max) then generated field gets varchar data type and that is it.
Here is the sample of the script.
foreach (var col in table.GetReferenced(Table.Columns))
{
string columnText;
string columnName = col.Name.Parts[2];
// this attempts to limit to only columns from the source. there's gotta be a cleaner way.
if (!skipColumns.Contains(columnName))
{
int length = col.GetProperty<int>(Column.Length);
int precision = col.GetProperty<int>(Column.Precision);
int scale = col.GetProperty<int>(Column.Scale);
string suffix;
if (length != 0)
{
suffix = String.Format("({0})", length);
}
else if (precision != 0)
{
suffix = String.Format("({0},{1})", precision, scale);
}
else if (precision == 0 && scale != 0)
{
suffix = String.Format("({0})", scale);
}
else
{
suffix = "";
}
bool nullable = col.GetProperty<bool>(Column.Nullable);
string nullText = nullable ? "NULL" : "NOT NULL";
string dataType = col.GetReferenced(Column.DataType).FirstOrDefault().Name.ToString();
columnText = String.Format("[{0}] {1}{2} {3}", columnName, dataType, suffix, nullText);
WriteLine(" " + columnText + ",");
}
}
How to handle varchar(max) in t4 script?
Here the answer.
You would have to use the following and then compare it.
bool isMax = col.GetProperty<bool>(Column.IsMax);
...
if (isMax)
{
suffix = String.Format("({0})", "max");
}
I was used Hex.encodeHexString(byte[] hexStringByteArray); api for convert byte array to String but in two different situations not able to get the excepted values.
Excepted String tcpPort = "1443";
In byte array [5,-93] --> In Hex String : 05a3
byte[] value1 = new byte[]{[5, -93]};
String tcpPort1 = Hex.encodeHexString(value1); // Incorrect value 05a3
Excepted String bufferSize = "0578";
In byte array [[5, 120] --> In Hex String : 0578
String bufferSize = "0578"; // in byte array [5,120]
byte[] value2 = new byte[]{[5, 120]};
String bufferSize = Hex.encodeHexString(value1); --- Correct value 0578
1 is incorrect and 2 is correct. Please help on this. I have to correct both values in same way.
I've created this two extensions in Kotlin to Encrypt/Decrypt strings:
fun String.encrypt(seed : String): String {
val keyGenerator = KeyGenerator.getInstance("AES")
val secureRandom = SecureRandom.getInstance("SHA1PRNG")
secureRandom.setSeed(seed.toByteArray())
keyGenerator.init(128, secureRandom)
val skey = keyGenerator.generateKey()
val rawKey : ByteArray = skey.encoded
val skeySpec = SecretKeySpec(rawKey, "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, skeySpec)
val byteArray = cipher.doFinal(this.toByteArray())
return byteArray.toString()
}
fun String.decrypt(seed : String): String {
val keyGenerator = KeyGenerator.getInstance("AES")
val secureRandom = SecureRandom.getInstance("SHA1PRNG")
secureRandom.setSeed(seed.toByteArray())
keyGenerator.init(128, secureRandom)
val skey = keyGenerator.generateKey()
val rawKey : ByteArray = skey.encoded
val skeySpec = SecretKeySpec(rawKey, "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.DECRYPT_MODE, skeySpec)
val byteArray = cipher.doFinal(this.toByteArray())
return byteArray.toString()
}
for some reason I'm getting the following exception:
javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
What I'm doing wrong?
AES Encryption / Decryption using base64 key, salt and iv (Initialization Vector).
object AESEncyption {
const val secretKey = "tK5UTui+DPh8lIlBxya5XVsmeDCoUl6vHhdIESMB6sQ="
const val salt = "QWlGNHNhMTJTQWZ2bGhpV3U=" // base64 decode => AiF4sa12SAfvlhiWu
const val iv = "bVQzNFNhRkQ1Njc4UUFaWA==" // base64 decode => mT34SaFD5678QAZX
fun encrypt(strToEncrypt: String) : String?
{
try
{
val ivParameterSpec = IvParameterSpec(Base64.decode(iv, Base64.DEFAULT))
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
val spec = PBEKeySpec(secretKey.toCharArray(), Base64.decode(salt, Base64.DEFAULT), 10000, 256)
val tmp = factory.generateSecret(spec)
val secretKey = SecretKeySpec(tmp.encoded, "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
return Base64.encodeToString(cipher.doFinal(strToEncrypt.toByteArray(Charsets.UTF_8)), Base64.DEFAULT)
}
catch (e: Exception)
{
println("Error while encrypting: $e")
}
return null
}
fun decrypt(strToDecrypt : String) : String? {
try
{
val ivParameterSpec = IvParameterSpec(Base64.decode(iv, Base64.DEFAULT))
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
val spec = PBEKeySpec(secretKey.toCharArray(), Base64.decode(salt, Base64.DEFAULT), 10000, 256)
val tmp = factory.generateSecret(spec);
val secretKey = SecretKeySpec(tmp.encoded, "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
return String(cipher.doFinal(Base64.decode(strToDecrypt, Base64.DEFAULT)))
}
catch (e : Exception) {
println("Error while decrypting: $e");
}
return null
}
}
iOS swift
Following Maarten Bodews guides I fix the issues as:
fun String.encrypt(password: String): String {
val secretKeySpec = SecretKeySpec(password.toByteArray(), "AES")
val iv = ByteArray(16)
val charArray = password.toCharArray()
for (i in 0 until charArray.size){
iv[i] = charArray[i].toByte()
}
val ivParameterSpec = IvParameterSpec(iv)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec)
val encryptedValue = cipher.doFinal(this.toByteArray())
return Base64.encodeToString(encryptedValue, Base64.DEFAULT)
}
fun String.decrypt(password: String): String {
val secretKeySpec = SecretKeySpec(password.toByteArray(), "AES")
val iv = ByteArray(16)
val charArray = password.toCharArray()
for (i in 0 until charArray.size){
iv[i] = charArray[i].toByte()
}
val ivParameterSpec = IvParameterSpec(iv)
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec)
val decryptedByteValue = cipher.doFinal(Base64.decode(this, Base64.DEFAULT))
return String(decryptedByteValue)
}
To encode your ciphertext use base 64 or hexadecimals. The Java API contains a Base64 class, so you're probably best off using that.
byte[]#toString doesn't do what you expect it to do; it simply returns a representation of the byte array reference, not the contents of the byte array.
Besides that:
don't use SecureRandom to derive a key, try and lookup PBKDF2;
explicitly use a mode of operation such as "AES/GCM/NoPadding";
use a unique IV, and a random IV if you decide to use CBC (usually insecure);
don't use toByteArray without explicitly selecting a character encoding for the message.
The easiest way of implementing AES Encryption and Decryption in Android is to copy this class in your projects.
Encrypt Strings
Please copy the AESUtils class in your project first and then you can use it like this.
String encrypted = "";
String sourceStr = "This is any source string";
try {
encrypted = AESUtils.encrypt(sourceStr);
Log.d("TEST", "encrypted:" + encrypted);
} catch (Exception e) {
e.printStackTrace();
}
Decrypt Strings
String encrypted = "ANY_ENCRYPTED_STRING_HERE";
String decrypted = "";
try {
decrypted = AESUtils.decrypt(encrypted);
Log.d("TEST", "decrypted:" + decrypted);
} catch (Exception e) {
e.printStackTrace();
}
AESUtils Class
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils
{
private static final byte[] keyValue =
new byte[]{'c', 'o', 'd', 'i', 'n', 'g', 'a', 'f', 'f', 'a', 'i', 'r', 's', 'c', 'o', 'm'};
public static String encrypt(String cleartext)
throws Exception {
byte[] rawKey = getRawKey();
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String encrypted)
throws Exception {
byte[] enc = toByte(encrypted);
byte[] result = decrypt(enc);
return new String(result);
}
private static byte[] getRawKey() throws Exception {
SecretKey key = new SecretKeySpec(keyValue, "AES");
byte[] raw = key.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKey skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] encrypted)
throws Exception {
SecretKey skeySpec = new SecretKeySpec(keyValue, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
16).byteValue();
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2 * buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
}
}
You can Encrypt and Decrypt in Kotlin like this
first you need:
val SECRET_KEY = "secretKey"
val SECRET_IV = "secretIV"
after that
Encrypt:
private fun String.encryptCBC(): String {
val iv = IvParameterSpec(SECRET_IV.toByteArray())
val keySpec = SecretKeySpec(SECRET_KEY.toByteArray(), "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv)
val crypted = cipher.doFinal(this.toByteArray())
val encodedByte = Base64.encode(crypted, Base64.DEFAULT)
return String(encodedByte)
}
and Decrypt:
private fun String.decryptCBC(): String {
val decodedByte: ByteArray = Base64.decode(this, Base64.DEFAULT)
val iv = IvParameterSpec(SECRET_IV.toByteArray())
val keySpec = SecretKeySpec(SECRET_KEY.toByteArray(), "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv)
val output = cipher.doFinal(decodedByte)
return String(output)
}
after that you can use it like this:
val strEncrypt = edt.text.toString().encryptCBC()
val strDecrypted = strEncrypt?.decryptCBC()
Following MarcForn guide I reduce it like this this:
const val encryptionKey = "ENCRYPTION_KEY"
fun String.cipherEncrypt(encryptionKey: String): String? {
try {
val secretKeySpec = SecretKeySpec(encryptionKey.toByteArray(), "AES")
val iv = encryptionKey.toByteArray()
val ivParameterSpec = IvParameterSpec(iv)
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec)
val encryptedValue = cipher.doFinal(this.toByteArray())
return Base64.encodeToString(encryptedValue, Base64.DEFAULT)
} catch (e: Exception) {
e.message?.let{ Log.e("encryptor", it) }
}
return null
}
fun String.cipherDecrypt(encryptionKey: String): String? {
try {
val secretKeySpec = SecretKeySpec(encryptionKey.toByteArray(), "AES")
val iv = encryptionKey.toByteArray()
val ivParameterSpec = IvParameterSpec(iv)
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec)
val decodedValue = Base64.decode(this, Base64.DEFAULT)
val decryptedValue = cipher.doFinal(decodedValue)
return String(decryptedValue)
} catch (e: Exception) {
e.message?.let{ Log.e("decryptor", it) }
}
return null
}