Encrypt/Decrypt String Kotlin - encryption

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
}

Related

Calling Netsuite SOAP .wsdl from C# .Net Core

First of all, I found this link which was a HUGE help to get this working.
https://medium.com/#benwmills/using-the-netsuite-suitetalk-api-with-net-core-net-standard-40f1a4464da1
But wanted to post my findings - in case it helps anyone else.
Step 1: Add a Service Reference to your project (WCF Web Service)
Step 2: Create NetSuitePortTypeClient and Open it (use your own account specific)
NetSuitePortTypeClient nsptc = new NetSuitePortTypeClient(NetSuitePortTypeClient.EndpointConfiguration.NetSuitePort, "https://########.suitetalk.api.netsuite.com/services/NetSuitePort_2021_2");
await nsptc.OpenAsync();
Step 3: Create a Transaction Search in this example
TransactionSearch tranSearch = new TransactionSearch();
TransactionSearchBasic tranSearchBasic = new TransactionSearchBasic();
SearchStringField searchstringfield = new SearchStringField();
searchstringfield.#operator = SearchStringFieldOperator.#is;
searchstringfield.operatorSpecified = true;
searchstringfield.searchValue = "$$$$$$";
tranSearchBasic.tranId = searchstringfield;
tranSearch.basic = tranSearchBasic;
Step 4: Call the Search
searchResponse sresponse = await nsptc.searchAsync(CreateTokenPassport(), null, null, null, tranSearch);
AND Here is the CreateTokenPassword function
public TokenPassport CreateTokenPassport()
{
string account = "account";
string consumerKey = "ckey";
string consumerSecret = "csecret";
string tokenId = "token";
string tokenSecret = "tokensecret";
string nonce = ComputeNonce();
long timestamp = ComputeTimestamp();
TokenPassportSignature signature = ComputeSignature(account, consumerKey, consumerSecret, tokenId, tokenSecret, nonce, timestamp);
TokenPassport tokenPassport = new TokenPassport();
tokenPassport.account = account;
tokenPassport.consumerKey = consumerKey;
tokenPassport.token = tokenId;
tokenPassport.nonce = nonce;
tokenPassport.timestamp = timestamp;
tokenPassport.signature = signature;
return tokenPassport;
}
You've left out the ComputeNonce, ComputeTimestamp, ComputeSignature functions so this code doesn't work...
Here is full code from example of calling NetSuite SOAP using C#:
public TokenPassport CreateTokenPassport()
{
string account = DataCollection["login.acct"];
string consumerKey = DataCollection["login.tbaConsumerKey"];
string consumerSecret = DataCollection["login.tbaConsumerSecret"];
string tokenId = DataCollection["login.tbaTokenId"];
string tokenSecret = DataCollection["login.tbaTokenSecret"];
string nonce = ComputeNonce();
long timestamp = ComputeTimestamp();
TokenPassportSignature signature = ComputeSignature(account, consumerKey, consumerSecret, tokenId, tokenSecret, nonce, timestamp);
TokenPassport tokenPassport = new TokenPassport();
tokenPassport.account = account;
tokenPassport.consumerKey = consumerKey;
tokenPassport.token = tokenId;
tokenPassport.nonce = nonce;
tokenPassport.timestamp = timestamp;
tokenPassport.signature = signature;
return tokenPassport;
}
private string ComputeNonce()
{
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] data = new byte[20];
rng.GetBytes(data);
int value = Math.Abs(BitConverter.ToInt32(data, 0));
return value.ToString();
}
private long ComputeTimestamp()
{
return ((long) (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}
private TokenPassportSignature ComputeSignature(string compId, string consumerKey, string consumerSecret,
string tokenId, string tokenSecret, string nonce, long timestamp)
{
string baseString = compId + "&" + consumerKey + "&" + tokenId + "&" + nonce + "&" + timestamp;
string key = consumerSecret + "&" + tokenSecret;
string signature = "";
var encoding = new System.Text.ASCIIEncoding();
byte[] keyBytes = encoding.GetBytes(key);
byte[] baseStringBytes = encoding.GetBytes(baseString);
using (var hmacSha1 = new HMACSHA1(keyBytes))
{
byte[] hashBaseString = hmacSha1.ComputeHash(baseStringBytes);
signature = Convert.ToBase64String(hashBaseString);
}
TokenPassportSignature sign = new TokenPassportSignature();
sign.algorithm = "HMAC-SHA1";
sign.Value = signature;
return sign;
}

Oracle "UPDATE" command returns 0 rows affected in my ASP .NET application but the SQL statement itself works in PL/SQL

I have this ASP.NET project working with Oracle, I have the following code for operating the DB:
public int cmd_Execute_Orcl(string strSql, params OracleParameter[] paramArray)
{
OracleCommand myCmd = new OracleCommand();
try
{
myCmd.Connection = myOrclConn;
myCmd.CommandText = strSql;
foreach (OracleParameter temp in paramArray)
{
myCmd.Parameters.Add(temp);
}
ConnectionManage(true);
int i = myCmd.ExecuteNonQuery();
myCmd.Parameters.Clear();
return i;
}
catch (Exception ex)
{
throw (ex);
}
finally
{
myCmd.Dispose();
ConnectionManage(false);
}
}
"ConnectionManage()" turns on or off the connection, the following code is from data access layer of the program:
public string Edit_DAL(string id, string jh, string jz, string jd, string wd, string gzwz, string qxlx, string sx, string jx, string jb, string cfdd, string zjqssj, string zjzzsj, string bz)
{
string sql = "update JH set jh = :jh, jz = :jz, wd = :wd, jd = :jd, gzwz = :gzwz, qxlx = :qxlx, sx = :sx, jx = :jx, jb = :jb, cfdd = :cfdd, zjqssj = TO_DATE(:zjqssj, 'yyyy-mm-dd hh24:mi:ss'), zjzzsj = TO_DATE(:zjzzsj, 'yyyy-mm-dd hh24:mi:ss'), bz = :bz where ID = :idy";
string result = null;
{
String[] temp1 = zjqssj.Split('/');
String[] temp2 = zjzzsj.Split('/');
string tempString = "";
if (temp1[2].Length < 2)
{
temp1[2] = temp1[2].Insert(0, "0");
}
for (int i = 0; i < temp1.Length; i++)
{
if (i != 0)
{
temp1[i] = temp1[i].Insert(0, "/");
}
tempString += temp1[i].ToString();
}
zjqssj = tempString;
tempString = "";
if (temp2[2].Length < 2)
{
temp2[2] = temp2[2].Insert(0, "0");
}
for (int i = 0; i < temp2.Length; i++)
{
if (i != 0)
{
temp2[i] = temp2[i].Insert(0, "/");
}
tempString += temp2[i].ToString();
}
zjzzsj = tempString;
tempString = "";
}
OracleParameter[] pars ={
new OracleParameter(":idy",id),
new OracleParameter(":jh",jh),
new OracleParameter(":jz",jz),
new OracleParameter(":jd",jd),
new OracleParameter(":wd",wd),
new OracleParameter(":gzwz",gzwz),
new OracleParameter(":qxlx",qxlx),
new OracleParameter(":sx",sx),
new OracleParameter(":jx",jx),
new OracleParameter(":jb",jb),
new OracleParameter(":cfdd",cfdd),
new OracleParameter(":zjqssj",(zjqssj.Replace('/', '-') + " 00:00:00")),
new OracleParameter(":zjzzsj",(zjzzsj.Replace('/', '-') + " 00:00:00")),
new OracleParameter(":bz",bz)
};
try
{
SqlHelper.cmd_Execute_Orcl(sql, pars);
result = "ok";
}
catch (Exception ex)
{
result = "no" + "=" + ex.Message + "\n" + ex.StackTrace;
}
return result;
}
Here's where the strange thing happens, when I hit this part of the code, there's no exception, it returns 0, no rows affected, all the values of the parameters are normal, with expected value, then I tried to run the command in PL/SQL and it works, the row is correctly updated, delete function is also referencing the same "cmd_Execute_Orcl" method and it works just fine, and for the other object the edit function is working perfectly, I am posting the code below:
public string Edit(string OriginalId, string EditUserAccount, string EditUserName, string EditUserMobile, string EditDeptId, string EditRoleId, string EditRoleName)
{
string sql = "update AuthUser set UserAccount=:EditUserAccount, UserName=:EditUserName, UserMobile=:EditUserMobile, DepartmentId=:EditDeptId, RID=:EditRoleId, RoleName=:EditRoleName where ID=:OriginalId";
OracleParameter[] pars ={
new OracleParameter(":EditUserAccount",EditUserAccount),
new OracleParameter(":EditUserName",EditUserName),
new OracleParameter(":EditUserMobile",EditUserMobile),
new OracleParameter(":EditDeptId",EditDeptId),
new OracleParameter(":EditRoleId",EditRoleId),
new OracleParameter(":EditRoleName",EditRoleName),
new OracleParameter(":OriginalId",OriginalId),
};
try
{
SqlHelper.cmd_Execute_Orcl(sql, pars);
return "ok";
}
catch (Exception ex)
{
string test = ex.Message;
return "no";
}
}
In the expected table, column ID is nvarchar2 with default value of sys_guid(), column ZJQSSJ and column ZJZZSJ is of type date, all other columns are of type varchar2, I have also tried executing "COMMIT" and reformating data for date, but the same problem is still there, plz help...

When I decrypt with AES in ASP.Net Core I lose some data

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);

How to get gmail attachment into local device store with intent filter

In my application i want to open gmail attachment with my application, i used intent filter for that,
I am getting URI and i want to use that and copy that attachment to my local device and want to display that with my application .
url = {content://com.google.android.gm.sapi/abc#gmail.com/message_attachment_external/%23thread-f%3A1610966348228029097/%23msg-f%3A1610966348228029097/0.1?account_type=com.google&mimeType=application%2Foctet-stream&rendition=1}
After a days of research and implementation, Here is a final solution for gmail attachment file , to view and down load in our application.
[IntentFilter(new string[] { Intent.ActionView }, Categories = new string[] { Intent.CategoryDefault, Intent.CategoryBrowsable }, DataScheme = "content", DataMimeType = "application/octet-stream")]
Stream inputsTream = resolver.OpenInputStream(url);
fs = File.Create(fileName);
byte[] buffer = new byte[32768];
int count;
int offset = 0;
while ((count = inputsTream.Read(buffer, offset, buffer.Length)) > 0)
{
fs.Write(buffer, 0, count);
}
fs.Close();
inputsTream.Close();
private fun deepLinkAcceptor(){
var ins: InputStream? = null
var os: FileOutputStream? = null
var fullPath: String? = null
var file: File;
try {
val action = intent.action
if (Intent.ACTION_VIEW != action) {
return
}
val uri = intent.data
val scheme = uri!!.scheme
var name: String? = null
if (scheme == "content") {
val cursor = contentResolver.query(
uri!!, arrayOf(
MediaStore.MediaColumns.DISPLAY_NAME
), null, null, null
)
cursor!!.moveToFirst()
val nameIndex = cursor!!.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
if (nameIndex >= 0) {
name = cursor!!.getString(nameIndex)
}
} else {
return
}
if (name == null) {
return
}
val n = name.lastIndexOf(".")
val fileName: String
val fileExt: String
if (n == -1) {
return
} else {
fileName = name.substring(0, n)
fileExt = name.substring(n)
}
// create full path to where the file is to go, including name/ext
fullPath = ""
val filenm = fileName + fileExt
file = File(cacheDir, filenm)
ins = contentResolver.openInputStream(uri!!)
os = FileOutputStream(file.getPath())
val buffer = ByteArray(4096)
var count: Int
while (ins!!.read(buffer).also { count = it } > 0) {
os!!.write(buffer, 0, count)
}
os!!.close()
ins!!.close()
println("===onfile path: " + file.getAbsolutePath())
println("===onFile name: " + file.readText())
} catch (e: Exception) {
if (ins != null) {
try {
ins.close()
} catch (e1: Exception) {
}
}
if (os != null) {
try {
os.close()
} catch (e1: Exception) {
}
}
if (fullPath != null) {
val f = File(fullPath)
f.delete()
}
}
}

AES EncryptN BADA solution

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()

Resources