I am trying to encrypt the communications between a java and a python app and the problem is I'm getting different result in decrypting the encrypted string from the other side in both apps.
I searched a lot but I didn't found any problem in the code and I will be much appreciated if you guide me in this.
Here is the encryption function in java side:
public static String encrypt(String value) {
try {
String privateKey = "1234567887654321";
String stringIV = getRandomIV();
IvParameterSpec iv = new IvParameterSpec(stringIV.getBytes());
SecretKeySpec skeySpec = new SecretKeySpec(privateKey.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
String encryptedString = new String(encrypted)
String toEncrypt = stringIV + encryptedString;
return android.util.Base64.encodeToString(toEncrypt.getBytes("UTF-8"), android.util.Base64.DEFAULT);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
static String getRandomIV() {
UUID randomUUID = UUID.randomUUID();
return randomUUID.toString().replaceAll("_", "").replaceAll("-", "").substring(0,16);
}
and here is the decryption part in python:
msg_bytes=bytes(msg, encoding="utf8").decode("utf-8",'ignore')
b64decoded=base64.b64decode(msg_bytes)
cipher = AES.new('1234567887654321'.encode("utf8"), AES.MODE_CBC, b64decoded[0:16])
decoded = cipher.decrypt(b64decoded[16:48])
decoded = bytes(decoded).decode("utf-8",'ignore')
I'm testing this with a 32 byte message and I'm getting different results with AES part, alse here is my java decryption function:
public static String decrypt(String encrypted) {
try {
String privateKey = "1234567887654321";
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
byte[] base64decoded = new byte[0];
base64decoded = android.util.Base64.decode(encrypted, android.util.Base64.DEFAULT);
String base64decodedString = new String(base64decoded);
byte[] byteiv = Arrays.copyOfRange(base64decoded, 0, 16);
IvParameterSpec iv = new IvParameterSpec(byteiv);
SecretKeySpec skeySpec = new SecretKeySpec(privateKey.getBytes(), "AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] bytes = Hex.decodeHex(hex(base64decodedString.substring(16,48).getBytes()).toCharArray());
byte[] original = new byte[0];
byte[] bytemsg = Arrays.copyOfRange(base64decoded, 16, base64decoded.length);
original = cipher.doFinal(bytemsg);
return new String(original.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
and also python's encryption:
data = str(json.dumps(data))
iv = Random.get_random_bytes(16)
cipher = AES.new('1234567887654321'.encode("utf8"), AES.MODE_CBC, iv)
byte_iv = bytearray(iv)
encrypted = bytearray(cipher.encrypt(self.pad(data).encode("utf8")))
data = base64.b64encode(bytes(byte_iv + encrypted))
data = list(data)
data = bytes(data)
Any help will be much appreciated.
I am trying to convert this Python code to C# (.NET Core ideally).
Source
My goal is to convert the QR input string to another string containing the data in json. See the provided links.
#! /usr/bin/env python3
import json
import sys
import zlib
import base45
import cbor2
from cose.messages import CoseMessage
payload = sys.argv[1][4:]
print("decoding payload: "+ payload)
# decode Base45 (remove HC1: prefix)
decoded = base45.b45decode(payload)
# decompress using zlib
decompressed = zlib.decompress(decoded)
# decode COSE message (no signature verification done)
cose = CoseMessage.decode(decompressed)
# decode the CBOR encoded payload and print as json
print(json.dumps(cbor2.loads(cose.payload), indent=2))
I couldn't find any NuGet package for Zlib, that would work correctly. So I am stuck straight after base45 decoding. Thanks for any tips.
using System.Text; //Rystem.Text.Base45 NuGet
var removedHeader = testQrData.Substring(4);
var decoded = removedHeader.FromBase45();
byte[] rawBytes = Encoding.ASCII.GetBytes(decoded);
This link might be helpful for further investigation.
Decoding scheme
IBarcodeReader reader = new BarcodeReader();//using Zxing
var barcodeBitmap = (Bitmap)Bitmap.FromFile("qrcode.png");
var barcodeReader = new BarcodeReader();
var qrcontent = barcodeReader.Decode(barcodeBitmap).Text;
var qrmessage = qrcontent.Substring(4);//remove first 4 chars
byte[] decodedBase45 = Base45Encoding.Decode(qrmessage);//using base45 lib
var cose = ZlibStream.UncompressBuffer(decodedBase45);//using zlib or similar
var decrypted = Message.DecodeFromBytes(cose).GetContent(); //using COSE
CBORObject cbor = CBORObject.DecodeFromBytes(decrypted); //using Peter.O.. CBOR
var jsonDecoded = cbor.ToJSONString(); //or deserialize it to custom class
I added "Zlib.Portable" from NuGet and used "ZlibStream.UncompressString"
byte[] decoded = Base45Encoding.Decode(input);
var stringResult = ZlibStream.UncompressString(decoded);`
I'm stuck in the next step "CoseMessage.decode" :/
I have used the ZXing library in the past to decode and create QR Codes:
https://github.com/micjahn/ZXing.Net
You could also try: https://github.com/codebude/QRCoder
A quick ZXing example from their github page:
// create a barcode reader instance
IBarcodeReader reader = new BarcodeReader();
// load a bitmap
var barcodeBitmap = (Bitmap)Image.LoadFrom("C:\\sample-barcode-image.png");
// detect and decode the barcode inside the bitmap
var result = reader.Decode(barcodeBitmap);
// do something with the result
if (result != null)
{
txtDecoderType.Text = result.BarcodeFormat.ToString();
txtDecoderContent.Text = result.Text;
}
This example reads a QR Code image.
I'm not sure what your input is but i would assume it's also an image in binary format so you might have to play around to get it working.
This solution works for me.
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using System;
using System.IO;
using Com.AugustCellars.COSE;
using PeterO.Cbor;
using Newtonsoft.Json;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Collections.Generic;
namespace DGCVerification.Services {
public class DGCVerificationService: IDGCVerificationService {
private readonly string _certificatePrefix = "HC1:";
private readonly ILogger < DGCVerificationService > _logger;
public DGCVerificationService(ILogger < DGCVerificationService > logger) {
_logger = logger;
}
private bool TryTrimPrefix(string certificateString, out string result) {
if (!certificateString.StartsWith(_certificatePrefix)) {
result = null;
return false;
}
result = certificateString.Substring(_certificatePrefix.Length);
return true;
}
private byte[] DecompressFromZlib(byte[] input) {
using(var memoryStream = new MemoryStream(input)) {
using(var decompressionStream = new InflaterInputStream(memoryStream)) {
using(var resultStream = new MemoryStream()) {
decompressionStream.CopyTo(resultStream);
var result = resultStream.ToArray();
return result;
}
}
}
}
private bool VerifyCoseSignature(Sign1Message coseMessage, string signature) {
var signatureAsBytes = Convert.FromBase64String(signature);
var publicKey = OneKey.FromX509(signatureAsBytes);
var result = coseMessage.Validate(publicKey);
_logger.LogInformation($"cose message signature {signature} verified as {result}");
return result;
}
private DGCPayload DecodeAndDeserialize(string certificateString, out Sign1Message coseMessage) {
coseMessage = null;
if (!TryTrimPrefix(certificateString, out
var trimmedPrefixString)) {
_logger.LogInformation($"certificate {certificateString} didn't have proper prefix {_certificatePrefix}");
return null;
}
var bytesBase256 = Base45Encoding.Decode(trimmedPrefixString);
_logger.LogInformation($"certificate {certificateString} base45 decoded to {Convert.ToBase64String(bytesBase256)}");
var decompressedFromZlib = DecompressFromZlib(bytesBase256);
_logger.LogDebug($"certificate {certificateString} zlib decompressed to {Convert.ToBase64String(decompressedFromZlib)}");
coseMessage = Message.DecodeFromBytes(decompressedFromZlib) as Sign1Message;
var coseMessagePayload = coseMessage.GetContent();
var cborResult = CBORObject.DecodeFromBytes(coseMessagePayload);
var jsonResult = cborResult.ToJSONString();
var result = JsonConvert.DeserializeObject < DGCPayloadCzechVersionRoot > (jsonResult);
return result.DGCPayloadWrap.DGCPayload;
}
private bool IsNotExpiredDGC(DGCPayload dGCPayload, UzisData uzisData) {
var vaccine = dGCPayload.Vaccination?.FirstOrDefault();
if (vaccine != null) {
var vaccinationValidityRules = uzisData.DGCValidityCzechRules.Rules
.FirstOrDefault()
.PlatnostiVakcinace;
var rule = vaccinationValidityRules.FirstOrDefault(x => x.VaccineMedicinalProduct == vaccine.Mp) ??
vaccinationValidityRules.FirstOrDefault(x => x.VaccineMedicinalProduct == null);
if (!DateTime.TryParse(vaccine.Dt, out
var vaccinatedOnDate)) {
_logger.LogError($"couldn't parse date of vaccination for DGC : {JsonConvert.SerializeObject(dGCPayload)}");
return false;
}
var result = DateTime.Now.Date <= vaccinatedOnDate.AddMonths(rule.OdolnostMesicDo);
return result;
}
var test = dGCPayload.Test?.FirstOrDefault();
if (test != null) {
var testValidityRule = uzisData.DGCValidityCzechRules.Rules
.FirstOrDefault()
.PlatnostiTestu
.FirstOrDefault(x => x.TypeOfTest == test.Tt);
if (!DateTime.TryParse(test.Tr, out
var testedOnDate)) {
_logger.LogError($"couldn't parse date of test for DGC : {JsonConvert.SerializeObject(dGCPayload)}");
return false;
}
var result = DateTime.Now.Date <= testedOnDate.AddHours(testValidityRule.PlatnostHod);
return result;
}
var recovery = dGCPayload.Recovery?.FirstOrDefault();
if (recovery != null) {
if (!DateTime.TryParse(recovery.Du, out
var recoveryValidUntil)) {
_logger.LogError($"couldn't parse recovert valid until for DGC : {JsonConvert.SerializeObject(dGCPayload)}");
return false;
}
var result = DateTime.Now.Date <= recoveryValidUntil;
return result;
}
return false;
}
private string GetCountryFromDGC(DGCPayload dGCPayload) {
var result = dGCPayload.Vaccination?.FirstOrDefault()?.Co ??
dGCPayload.Test?.FirstOrDefault()?.Co ??
dGCPayload.Recovery?.FirstOrDefault()?.Co;
if (result == null) {
throw new ArgumentException($"couldn't retrieve country from DGC. dgc : {JsonConvert.SerializeObject(dGCPayload)}");
}
return result;
}
private List < SignatureCertificate > GetFittingSignatures(DGCPayload dGCPayload, UzisData uzisData) {
try {
var country = GetCountryFromDGC(dGCPayload);
var result = uzisData.NationalCertificateSignatures.SignatureCertificate
.Where(x => x.Active)
.Where(x => x.Country == country)
.Where(x => x.CertificateType == "DSC")
.ToList();
return result;
} catch (Exception e) {
_logger.LogError(e, $"Filtering signatures from UZIS failed with exception");
return null;
}
}
private bool IsProperlySignedDGC(string certificateString, DGCPayload dGCPayload, Sign1Message coseMessage, UzisData uzisData) {
var fittingSignatures = GetFittingSignatures(dGCPayload, uzisData);
var result = false;
foreach(var signature in fittingSignatures) {
try {
var signatureVerificationResult = VerifyCoseSignature(coseMessage, signature.RawData);
_logger.LogInformation($"certificate {certificateString} signature validation against signature {signature} resulted in {signatureVerificationResult}");
result |= signatureVerificationResult;
} catch (Exception e) {
_logger.LogError(e, $"certificate {certificateString} signature validation against signature {signature} failed with exception");
}
}
return result;
}
public bool IsValidDgc(string certificateString, UzisData uzisData, out DGCPayload decodedDGCPayload, out VerificationResult verificationResult) {
decodedDGCPayload = null;
Sign1Message coseMessage = null;
try {
decodedDGCPayload = DecodeAndDeserialize(certificateString, out coseMessage);
if (coseMessage == null) {
_logger.LogInformation($"certificate {certificateString} decoded to null COSE");
verificationResult = VerificationResult.UnableToDecode;
return false;
}
} catch (Exception e) {
_logger.LogError(e, $"certificate {certificateString} decoding failed with exception");
verificationResult = VerificationResult.UnableToDecode;
return false;
}
var isProperlySigned = IsProperlySignedDGC(certificateString, decodedDGCPayload, coseMessage, uzisData);
if (!isProperlySigned) {
verificationResult = VerificationResult.InvalidSignature;
return false;
}
var isNotExpired = IsNotExpiredDGC(decodedDGCPayload, uzisData);
if (!isNotExpired) {
verificationResult = VerificationResult.Expired;
return false;
}
verificationResult = VerificationResult.Valid;
return true;
}
}
}
And the tricky base45
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DGCVerification
{
public class Base45Encoding
{
private static readonly Dictionary<byte, char> _encodingTable = new Dictionary<byte, char>
{
{0x0,'0'},
{0x1,'1'},
{0x2,'2'},
{0x3,'3'},
{0x4,'4'},
{0x5,'5'},
{0x6,'6'},
{0x7,'7'},
{0x8,'8'},
{0x9,'9'},
{0xA,'A'},
{0xB,'B'},
{0xC,'C'},
{0xD,'D'},
{0xE,'E'},
{0xF,'F'},
{0x10,'G'},
{0x11,'H'},
{0x12,'I'},
{0x13,'J'},
{0x14,'K'},
{0x15,'L'},
{0x16,'M'},
{0x17,'N'},
{0x18,'O'},
{0x19,'P'},
{0x1A,'Q'},
{0x1B,'R'},
{0x1C,'S'},
{0x1D,'T'},
{0x1E,'U'},
{0x1F,'V'},
{0x20,'W'},
{0x21,'X'},
{0x22,'Y'},
{0x23,'Z'},
{0x24,' '},
{0x25,'$'},
{0x26,'%'},
{0x27,'*'},
{0x28,'+'},
{0x29,'-'},
{0x2A,'.'},
{0x2B,'/'},
{0x2C,':'},
};
private static readonly Dictionary<char, byte> _decodingTable;
static Base45Encoding()
{
_decodingTable = _encodingTable.ToDictionary(x => x.Value, x => x.Key);
}
private static List<byte> ToBytesBase45(string charsBase45)
{
var result = new List<byte>(charsBase45.Length);
foreach (var character in charsBase45)
{
if (!_decodingTable.TryGetValue(character, out byte asByte))
{
throw new FormatException($"input string contains {character} with numeric value {char.GetNumericValue(character)} on index {charsBase45.IndexOf(character)} which is not valid base45 character");
}
result.Add(asByte);
}
return result;
}
private static List<ushort> ToShortsBase10(List<byte> bytesBase45)
{
var result = new List<ushort>(bytesBase45.Count);
ushort num = 0;
double pow = 0;
for (int i = 0; i != bytesBase45.Count; ++i, ++pow)
{
num += (ushort)(bytesBase45[i] * Math.Pow(45, pow));
if (pow == 2 || i == (bytesBase45.Count -1))
{
result.Add(num);
num = 0;
pow = -1;
}
}
return result;
}
private static List<byte> ToBytesBase256(List<ushort> shortsBase10, int charBase45Length)
{
var result = new List<byte>(shortsBase10.Count);
for (int i = 0; i != shortsBase10.Count; ++i)
{
var num = (byte)(shortsBase10[i] / 256);
if(!(i == (shortsBase10.Count - 1)
&& charBase45Length % 3 != 0
&& num == 0))
{
result.Add(num);
}
result.Add((byte)(shortsBase10[i] % 256));
}
return result;
}
public static byte[] Decode(string charsBase45)
{
if (charsBase45.Length % 3 == 1)
{
throw new FormatException("input string does not have correct length. mod 3 == 1. it isnt base45");
}
var bytesBase45 = ToBytesBase45(charsBase45);
var shortsBase10 = ToShortsBase10(bytesBase45);
var bytesBase256 = ToBytesBase256(shortsBase10, charsBase45.Length);
return bytesBase256.ToArray();
}
}
}
Decode/encode base45:
/// <summary>
/// https://tools.ietf.org/html/draft-faltstrom-baseBaseSize-01
/// TL/DR:
/// This encoding takes a byte array, splits it into 2 byte chunks and encodes each chunk as 3 characters.
/// Any remaining byte is encoded as 2 characters, padded with a '0' when the remaining byte has value < 45.
/// </summary>
public static class Base45Encoding
{
private const int BaseSize = 45;
private const int BaseSizeSquared = 2025;
private const int ChunkSize = 2;
private const int EncodedChunkSize = 3;
private const int SmallEncodedChunkSize = 2;
private const int ByteSize = 256;
private static readonly char[] _Encoding = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*',
'+', '-', '.', '/', ':' };
private static readonly Dictionary<char, byte> _Decoding = new(BaseSize);
static Base45Encoding()
{
for(byte i = 0; i < _Encoding.Length; ++i)
_Decoding.Add(_Encoding[i], i);
}
public static string Encode(byte[] buffer)
{
if (buffer == null)
throw new ArgumentNullException(nameof(buffer));
var wholeChunkCount = buffer.Length / ChunkSize;
var result = new char[wholeChunkCount * EncodedChunkSize + (buffer.Length % ChunkSize == 1 ? SmallEncodedChunkSize : 0)];
if (result.Length == 0)
return string.Empty;
var resultIndex = 0;
var wholeChunkLength = wholeChunkCount * ChunkSize;
for (var i = 0; i < wholeChunkLength;)
{
var value = buffer[i++] * ByteSize + buffer[i++];
result[resultIndex++] = _Encoding[value % BaseSize];
result[resultIndex++] = _Encoding[value / BaseSize % BaseSize];
result[resultIndex++] = _Encoding[value / BaseSizeSquared % BaseSize];
}
if (buffer.Length % ChunkSize == 0)
return new string(result);
result[^2] = _Encoding[buffer[^1] % BaseSize];
result[^1] = buffer[^1] < BaseSize ? _Encoding[0] : _Encoding[buffer[^1] / BaseSize % BaseSize];
return new string(result);
}
public static byte[] Decode(string value)
{
if (value == null)
throw new ArgumentNullException(nameof(value));
if (value.Length == 0)
return Array.Empty<byte>();
var remainderSize = value.Length % EncodedChunkSize;
if (remainderSize == 1)
throw new FormatException("Incorrect length.");
var buffer = new byte[value.Length];
for (var i = 0; i < value.Length; ++i)
{
if (_Decoding.TryGetValue(value[i], out var decoded))
{
buffer[i] = decoded;
continue; //Earliest return on expected path.
}
throw new FormatException($"Invalid character at position {i}.");
}
var wholeChunkCount = buffer.Length / EncodedChunkSize;
var result = new byte[wholeChunkCount * ChunkSize + (remainderSize == ChunkSize ? 1 : 0)];
var resultIndex = 0;
var wholeChunkLength = wholeChunkCount * EncodedChunkSize;
for (var i = 0; i < wholeChunkLength; )
{
var val = buffer[i++] + BaseSize * buffer[i++] + BaseSizeSquared * buffer[i++];
result[resultIndex++] = (byte)(val / ByteSize); //result is always in the range 0-255 - % ByteSize omitted.
result[resultIndex++] = (byte)(val % ByteSize);
}
if (remainderSize == 0)
return result;
result[^1] = (byte)(buffer[^2] + BaseSize * buffer[^1]); //result is always in the range 0-255 - % ByteSize omitted.
return result;
}
}
How to convert below code in Python so that it gives same value on Windows even when executed multiple times.
Basically, it hashing password using sha512 and salt with 1000 iterations.
Here is the code:
using System;
using System.Security.Cryptography;
using System.Text;
namespace CheckHashing
{
class Program
{
protected static string CreateSHA512Hash(string Password, string Salt)
{
try
{
byte[] bytes_password = Encoding.UTF8.GetBytes(Password);
byte[] bytes_salt = Encoding.UTF8.GetBytes(Salt);
HashAlgorithm sha512hash = (HashAlgorithm)new SHA512CryptoServiceProvider();
for (int index = 0; index < 1000; ++index)
{
byte[] bytes_iteration = Encoding.UTF8.GetBytes(Convert.ToBase64String(bytes_password) + Convert.ToBase64String(bytes_salt));
bytes_password = sha512hash.ComputeHash(bytes_iteration);
}
return Convert.ToBase64String(bytes_password);
}
catch (Exception ex)
{
return "Exception"+ex.Message;
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
string hash_pwd = CreateSHA512Hash("Pass#21", "SALT(}");
Console.WriteLine(hash_pwd);
// Answer => HoCg9kKAl5WY0lWzvH7hdW+cTQGUfknALKDw49rvzUVUTt9X9fuggGpDIRfCdotR/kVU8m7gj2xzRzwIfDc5Xw==
}
}
}
Already tried below code which gives different values. Below output gives Invalid Password as error in the function.
import hashlib
from base64 import b64encode
password = "Pass#21"
salt = "SALT(}"
h = hashlib.pbkdf2_hmac('sha512', password.encode('utf-8'), salt.encode('utf-8'), 1000)
print(b64encode(h).decode())
# and below as well
hex_hash = hashlib.sha512(password.encode('utf-8') + salt.encode('utf-8')).digest()
for i in range(1000):
hex_hash = hashlib.sha512(hex_hash + salt.encode('utf-8')).digest()
print(b64encode(hex_hash).decode())
from passlib.hash import sha512_crypt as sha512
sha512_passwd = sha512.hash(password, rounds=1000)
print(sha512_passwd)
They don't start out the same.
If you add some prints to the C#
protected static string CreateSHA512Hash(string Password, string Salt)
{
try
{
byte[] bytes_password = Encoding.UTF8.GetBytes(Password);
byte[] bytes_salt = Encoding.UTF8.GetBytes(Salt);
HashAlgorithm sha512hash = (HashAlgorithm)new SHA512CryptoServiceProvider();
for (int index = 0; index < 1000; ++index)
{
if (index < 10)
Console.WriteLine(Convert.ToBase64String(bytes_password));
byte[] bytes_iteration = Encoding.UTF8.GetBytes(Convert.ToBase64String(bytes_password) + Convert.ToBase64String(bytes_salt));
bytes_password = sha512hash.ComputeHash(bytes_iteration);
}
Console.WriteLine("...");
return Convert.ToBase64String(bytes_password);
}
catch (Exception ex)
{
return "Exception" + ex.Message;
}
}
Here's my python port of the same code, with the same debug prints, so you can compare the first 10 values.
import hashlib
from base64 import b64encode
password = "Pass#21"
salt = "SALT(}"
bytes_password = password.encode('utf-8')
bytes_salt = salt.encode('utf-8')
for i in range(1000):
if i < 10:
print(b64encode(bytes_password).decode())
b64pw = b64encode(bytes_password).decode()
b64sa = b64encode(bytes_salt).decode()
bytes_iteration = (b64pw + b64sa).encode('utf-8')
bytes_password = hashlib.sha512(bytes_iteration).digest()
print('...')
print(b64encode(bytes_password).decode())
Your original code wasn't consistent on when it hex encoded and when it computed the hash, and it computed a hash prior to entering the loop.
I can't figure out the image data send error, not familiar with JSON.
Given this working Python code:
def uploadImage(image_name, folder_path, location):
path = folder_path + '\\' + image_name
with open(path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
req_body = {"filename": image_name, "location": location}
resp_post = requests.post( "myURL", json=req_body)
if resp_post.status_code == 200:
url = resp_post_json = resp_post.json()['url'] # facing c# problem here
resp_put = requests.put(url,data=encoded_string)
if resp_put.status_code != 200:
return "PUT request error : {}".format(resp_put.reason)
else:
retur
"POST request error : {}".format(resp_post.reason)
C# code:
internal void UploadImage(string strImagePathNName, string strImageName, string strLoaction)
{
try
{
// read file in base 64 string
string base64String = Convert.ToBase64String(File.ReadAllBytes(strImagePathNName));
if (base64String.Length > 0)
{
var webAddr = "myURL";
string json = "{\"filename\":\"" + strImageName + "\"," + "\"location\":\"" + strLoaction + "\"}";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Close();
}
bool bIsGotResponseFromServer = false;
var strResponseUri = string.Empty;
using (HttpWebResponse webResponse = (HttpWebResponse)httpWebRequest.GetResponse())
{
if (webResponse.StatusCode == HttpStatusCode.OK)
{
using (Stream respStream = webResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream, Encoding.UTF8);
strResponseUri = reader.ReadToEnd();
UrlFromJson myojb = (UrlFromJson)JsonConvert.DeserializeObject(strResponseUri, typeof(UrlFromJson));
strResponseUri = myojb.url; //retrieved the URl
bIsGotResponseFromServer = true;
}
}
}
if (bIsGotResponseFromServer)
{
httpWebRequest = (HttpWebRequest)WebRequest.Create(strResponseUri);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "post";
json = "{\"data\":\"" + base64String + "\"}";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json); /// not sure about this line
streamWriter.Close();
}
using (HttpWebResponse webResponse1 = (HttpWebResponse)httpWebRequest.GetResponse()) // received error here
{
if (webResponse1.StatusCode == HttpStatusCode.OK)
{
}
}
}
}
}
catch (WebException e)
{
}
}
Solution
Just using the base64 string instead of the httpWebRequest.GetRequestStream:
Stream.Write(base64String,0, base64String.Length);
and set:
httpWebRequest.Method = "PUT";