Crypto-SDK C# EncryptFileKey error
Hello DRACOON team!
I've faced with some problems with implementing FileEncryption into our product with your crypto-sdk-c#
For example I got an error in EncryptFileKey function which says that "input data too long".
Here is the stackTrace:
at Org.BouncyCastle.Crypto.Encodings.OaepEncoding.EncodeBlock(Byte[] inBytes, Int32 inOff, Int32 inLen)
at Org.BouncyCastle.Crypto.Encodings.OaepEncoding.ProcessBlock(Byte[] inBytes, Int32 inOff, Int32 inLen)
at Dracoon.Crypto.Sdk.Crypto.EncryptFileKey(PlainFileKey plainFileKey, UserPublicKey userPublicKey) in C:\PROJECTS\..\DracoonCryptoSdk\Crypto.cs:line 243
BouncyCastle was installed latest version from Nuget.
So, can anyone please guide me about encrypting file implementation with this SDK?
-
Hello Vladimirs,
Currently I can only reproduce the error you decribed if I instantiate the PlainFileKey by my own with a PlainFileKey.Key longer than 190 bytes. Can you please check the length of your used PlainFileKey.Key?
Additonally, can you give me your used PublicKey and FileKey?
Kind regards
-
Hello Andreas!
So, from Dim fileKey = Crypto.GenerateFileKey() I get fileKey.key.length = 44 characters... but on SO I found that I need 16/24/32 characters..... so is there something wrong, or?
file key:
Name Value Type iv "7rBQbsj8FiV/K4XQ" String [key] "CYGk0thEIg27qPMoKddhQFLbIqVx+xPu1MTt1TYczgs=" String tag Nothing String version "A" String userKey:
{Dracoon.Crypto.Sdk.Model.UserPublicKey}
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzmSZm6g0xm+AT97NwnCj
70ric943ATV5JF3N1eG5X3N1dLXUJ7bIquOFtOFBJR+H8Nu/Cu5S8Y6Pv9ERddxK
4BaSN7kK8nEMPyktZu2QGWOwpfFOU8BzFjJ3OXfUfMqbRXKdWaZ4H9tt9chAOY3t
d57gJmLjNxbHYrdtcvrsiU2j/IHYf+KZg/fwWOzK6VTESYUPdiV0BN0RELP1eZdg
4lPjhPEreKQiV/H1eSR9DQvhVwsyaEdloPiWQNKYGdH3ArCk/SxAlccfcdzvgZdY
cPHyoPZG35USK2aILhunWN3+D6CRpOa2ExgazvdY+GbPqsnb5FeoZBdCxipnNjMe
tQIDAQAB
-----END PUBLIC KEY----- -
Hello Vladimirs,
The key has a length of 44 because it is BASE64-formatted. The unformatted key is of length 32.
If I use your values for testing in the following way:PlainFileKey fk = new PlainFileKey() {
Key = "CYGk0thEIg27qPMoKddhQFLbIqVx+xPu1MTt1TYczgs=",
Version = "A"
};
UserPublicKey upk = new UserPublicKey() {
PublicKey = "-----BEGIN PUBLIC KEY-----\r\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzmSZm6g0xm+AT97NwnCj\r\n70ric943ATV5JF3N1eG5X3N1dLXUJ7bIquOFtOFBJR+H8Nu/Cu5S8Y6Pv9ERddxK\r\n4BaSN7kK8nEMPyktZu2QGWOwpfFOU8BzFjJ3OXfUfMqbRXKdWaZ4H9tt9chAOY3t\r\nd57gJmLjNxbHYrdtcvrsiU2j/IHYf+KZg/fwWOzK6VTESYUPdiV0BN0RELP1eZdg\r\n4lPjhPEreKQiV/H1eSR9DQvhVwsyaEdloPiWQNKYGdH3ArCk/SxAlccfcdzvgZdY\r\ncPHyoPZG35USK2aILhunWN3+D6CRpOa2ExgazvdY+GbPqsnb5FeoZBdCxipnNjMe\r\ntQIDAQAB\r\n-----END PUBLIC KEY-----",
Version = "A"
};
EncryptedFileKey efk = Crypto.EncryptFileKey(fk, upk);then I don't get any errors and the efk is correct.
Can you give me a demo project implementation where your error occurs?
Kind regards
-
Hello Andreas!
Can you please explain me how exactly is working this SDK, because documentation is very small?
So what i'm doing for now:
1. I can upload encrypted files to DRACOON without any exceptions now. Code which is responsible for that:
Dim fileKey = Crypto.GenerateFileKey()
Dim uploadedFileAsByteArray As Byte() = Nothing
Dim userKeyPair = Crypto.GenerateUserKeyPair(userPWD)
Dim encFileKey = Nothing
Dim timeStamp As DateTime = Now()
Dim encryptedFilePath As String = System.IO.Path.GetTempPath & timeStamp.ToFileTime.ToString & upData("file_path").Substring(upData("file_path").LastIndexOf("\") + 1)
Using wc As New System.Net.WebClient()
wc.Headers.Add("X-Sds-Auth-Token", token)
Dim data() As Byte = File.ReadAllBytes(upData("file_path"))
File.WriteAllBytes(encryptedFilePath, data)
Dim uploadedEncryptedFileAsByteArray As Byte() = RDXCryptoHelper.EncryptData(fileKey, data)
encFileKey = Crypto.EncryptFileKey(fileKey, userKeyPair.UserPublicKey)
uploadedFileAsByteArray = wc.UploadFile(apiUrl, encryptedFilePath)
End Using
Dim dataBytes As Byte() = Nothing
Dim json As Object
httpWebRequest.Method = "PUT"
httpWebRequest.ContentType = "application/json"
httpWebRequest.Headers.Add("X-Sds-Auth-Token:" & token)
Dim userFileKeyList As New Dictionary(Of String, Object)
Dim userFileKeyListItemsItem As New Dictionary(Of String, Object)
userFileKeyListItemsItem.Add("userId", userID)
userFileKeyListItemsItem.Add("fileKey", encFileKey)
Dim userFileKeyListItemsItemAsObject As New List(Of Object)
userFileKeyListItemsItemAsObject.Add(userFileKeyListItemsItem)
userFileKeyList.Add("items", userFileKeyListItemsItemAsObject)
Dim post As New Dictionary(Of String, Object)
post.Add("resolutionStrategy", "overwrite")
post.Add("keepShareLinks", True)
post.Add("fileName", upData("file_path").Substring(upData("file_path").LastIndexOf("\") + 1))
post.Add("fileKey", encFileKey)
post.Add("userFileKeyList", userFileKeyList)
dataBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(post, Formatting.Indented))
httpWebRequest.ContentLength = dataBytes.Length
Using responseStream As Stream = httpWebRequest.GetRequestStream()
responseStream.Write(dataBytes, 0, dataBytes.Length)
End Using
httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
Using streamResponse As Stream = httpResponse.GetResponseStream
Dim str As New StreamReader(streamResponse)
responseFromServer = str.ReadToEnd()
End UsingAfter that, I can see files in WEB.... but, I can't download them from web (only from my application).... so does downloading from WEB require some extras which are not described in documentation or my steps contain some errors?
2. This problem goes from first problem... I can't download files I've uploaded to DRACOON from WEB from my application (I can do it only if files were uploaded directly from my app). So the code which is responsible for it:Dim httpWebRequest As HttpWebRequest = DirectCast(HttpWebRequest.Create(New Uri(url)), HttpWebRequest)
Dim httpResponse As HttpWebResponse
httpWebRequest.Method = "GET"
httpWebRequest.Headers.Add("X-Sds-Auth-Token:" & token)
httpWebRequest.Timeout = 600000
httpWebRequest.Accept = "application/octet-stream"
httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
Dim userKeyPair = Nothing
Dim userPass As String = Nothing
Using streamResponse As Stream = httpResponse.GetResponseStream
Using fs As New FileStream(localTempFile, FileMode.Create, FileAccess.Write)
'Need to decript here
If isFileEncripted Then
If Application.OpenForms().OfType(Of RDXEncryption).Any Then
frmEncription.Close()
frmEncription.Dispose()
End If
frmEncription = New RDXEncryption(_Parameter)
frmEncription.formOpenDocument = Me.formOpenDocument
frmEncription.frmRDX = Me
frmEncription.txt_encriptionPWD2.Hide()
Dim result As DialogResult = frmEncription.ShowDialog()
If result = DialogResult.OK Then
userPass = frmEncription.txt_encriptionPWD1.Text
userKeyPair = Crypto.GenerateUserKeyPair(userPass)
If Not Crypto.CheckUserKeyPair(userKeyPair, userPass) Then
ShowMessage(trCode("Invalid user password!"), System.Windows.Forms.MessageBoxIcon.Error, extractRdoxMessage:=True)
End If
End If
End If
Dim tBLL As SR_RDX.RDXBLLClient = GetRDXLayer()
Dim fileID = url.Substring(url.LastIndexOf("files/") + 6).Split("/")(0)
Dim postData As New Dictionary(Of String, Object)
postData.Add("X-Sds-Auth-Token:", token)
Dim userFileKey = JsonConvert.DeserializeObject(tBLL.GetJsonResponse(apiRoot & "nodes/files/" & fileID & "/user_file_key", "GET", postData, Nothing, Nothing, Nothing))
Dim dracoonFileKey As Model.PlainFileKey = New Model.PlainFileKey()
dracoonFileKey.iv = userFileKey("iv")
dracoonFileKey.key = userFileKey("key")
dracoonFileKey.tag = userFileKey("tag")
dracoonFileKey.version = userFileKey("version")
Dim encFileKey = Crypto.EncryptFileKey(dracoonFileKey, userKeyPair.UserPublicKey)
Dim decFileKey = Crypto.DecryptFileKey(encFileKey, userKeyPair.UserPrivateKey, userPass)
streamResponse.CopyTo(fs)
streamResponse.Close()
fs.Flush()
fs.Close()
Dim data() As Byte = System.IO.File.ReadAllBytes(fs.Name)
Dim uploadedEncryptedFileAsByteArray As Byte() = RDXCryptoHelper.DecryptData(decFileKey, data)
System.IO.File.WriteAllBytes(localTempFile, uploadedEncryptedFileAsByteArray)
End Using
End UsingSo what I'm doing wrong?
-
Hello Vladimirs,
OK, now I can see the problem. For downloading an encrypted file, you also have to download your user key pair that was used for the upload. This must be decrypted with the corresponding password to get the plain file key. Now it can be used to decrypt the file.
Probably I can now also see why you get the "input data too long" exception at the beginning of this topic --> your downloaded key is still encrypted which means its length is 256 (without base64 encoding). This is longer than the maximum of 190 bytes mentioned in a previous post.
Your download example should be more like the following:Dim userFileKey = JsonConvert.DeserializeObject(tBLL.GetJsonResponse(apiRoot & "nodes/files/" & fileID & "/user_file_key", "GET", postData, Nothing, Nothing, Nothing))
Dim dracoonFileKey As Model.EncryptedFileKey = New Model.EncryptedFileKey()
dracoonFileKey.iv = userFileKey("iv")
dracoonFileKey.key = userFileKey("key")
dracoonFileKey.tag = userFileKey("tag")
dracoonFileKey.version = userFileKey("version")
// You have to download the user key pair from the server and not generate a new one
Dim decFileKey = Crypto.DecryptFileKey(encFileKey, downloadedUserKeyPair.UserPrivateKey, passForDownloadedUserKeyPair)The same for your upload. If you want to upload an encrypted file, you have to download your user key pair from the server first and use this for your encryption.
I hope this helps.
Kind regards
(By the way: We also have an API SDK, which supports encrypted downloads/uploads if you want to check the implementations there. https://github.com/dracoon/dracoon-csharp-sdk)
-
So, if I understood correctly:
1 - uploading file going with:
Dim fileKey = Crypto.GenerateFileKey()
Dim userKeyPair = Crypto.GenerateUserKeyPair(userPWD)
encFileKey = Crypto.EncryptFileKey(fileKey, userKeyPair.UserPublicKey)2 - when i'm downloading this file (which i've been uploaded), I need to do:
Dim _accountKeyPair = JsonConvert.DeserializeObject(tBLL.GetJsonResponse(apiRoot & "user/account/keypair", "GET", _postData, Nothing, Nothing, Nothing))
Dim upk As New Model.UserPublicKey()
upk.PublicKey = _accountKeyPair("publicKeyContainer")("publicKey")
upk.Version = _accountKeyPair("publicKeyContainer")("version")
Dim upp As New Model.UserPrivateKey()
upp.PrivateKey = _accountKeyPair("privateKeyContainer")("privateKey")
upp.Version = _accountKeyPair("privateKeyContainer")("version")
Dim _userKeyPair As New Model.UserKeyPair()
_userKeyPair.UserPrivateKey = upp
_userKeyPair.UserPublicKey = upk
Dim userFileKey = JsonConvert.DeserializeObject(tBLL.GetJsonResponse(apiRoot & "nodes/files/" & fileID & "/user_file_key", "GET", postData, Nothing, Nothing, Nothing))
Dim encryptedFKFromRDX As Model.EncryptedFileKey = New Model.EncryptedFileKey()
encryptedFKFromRDX.iv = userFileKey("iv")
encryptedFKFromRDX.key = userFileKey("key")
encryptedFKFromRDX.tag = userFileKey("tag")
encryptedFKFromRDX.version = userFileKey("version")
Dim decFileKey_2 = Crypto.DecryptFileKey(encryptedFKFromRDX, userKeyPair.UserPrivateKey, userPass, True)
Dim uploadedEncryptedFileAsByteArray As Byte() = RDXCryptoHelper.DecryptData(decFileKey_2, data)Is it right?
-
Hi Vladimirs,
We also have a technical whitepaper that explains how the cryptography works, which you might find helpful:
https://heroes.dracoon.com/#/public/shares-downloads/3s58EjaJ7tg7PgARdzftLkrTnHdPPpZn
Best regards,
Michael
-
thanks for helping with this problem...
no I can start decryption of downloaded file, but, I'm using your GitHub example => https://github.com/dracoon/dracoon-csharp-crypto-sdk/blob/master/DracoonCryptoSdkExample/Program.cs
without any modifications, and I got another error in DecryptData function I got an exception => mac check in GCM failed
can you please help with it?
-
Hey Vladimirs,
In your post 1 month ago your download seems to be correct.
The problem is still in your upload. I have used your earlier posted code and commented the point were you have been wrong.```
// UPLOAD
Dim fileKey = Crypto.GenerateFileKey()
Dim uploadedFileAsByteArray As Byte() = Nothing
Dim userKeyPair = // Download user key pair from server over the endpoint (if it exists): GET https://yourserver/v4/user/account/keypair
// OTHERWISE: ONLY THEN generate a new key pair and upload this over the endpoint: POST https://yourserver/v4/user/account/keypair
// FROM KNOW you have to download (or cache) the key pair every time otherwise you will can't never decrypt the files again
Dim encFileKey = Nothing
Dim timeStamp As DateTime = Now()
Dim encryptedFilePath As String = System.IO.Path.GetTempPath & timeStamp.ToFileTime.ToString & upData("file_path").Substring(upData("file_path").LastIndexOf("\") + 1)
Using wc As New System.Net.WebClient()
wc.Headers.Add("X-Sds-Auth-Token", token)
Dim data() As Byte = File.ReadAllBytes(upData("file_path"))
File.WriteAllBytes(encryptedFilePath, data)
Dim uploadedEncryptedFileAsByteArray As Byte() = RDXCryptoHelper.EncryptData(fileKey, data)
encFileKey = Crypto.EncryptFileKey(fileKey, userKeyPair.UserPublicKey)
uploadedFileAsByteArray = wc.UploadFile(apiUrl, encryptedFilePath)
End Using
Dim dataBytes As Byte() = Nothing
Dim json As Object
httpWebRequest.Method = "PUT"
httpWebRequest.ContentType = "application/json"
httpWebRequest.Headers.Add("X-Sds-Auth-Token:" & token)
Dim userFileKeyList As New Dictionary(Of String, Object)
Dim userFileKeyListItemsItem As New Dictionary(Of String, Object)
userFileKeyListItemsItem.Add("userId", userID)
userFileKeyListItemsItem.Add("fileKey", encFileKey)
Dim userFileKeyListItemsItemAsObject As New List(Of Object)
userFileKeyListItemsItemAsObject.Add(userFileKeyListItemsItem)
userFileKeyList.Add("items", userFileKeyListItemsItemAsObject)
Dim post As New Dictionary(Of String, Object)
post.Add("resolutionStrategy", "overwrite")
post.Add("keepShareLinks", True)
post.Add("fileName", upData("file_path").Substring(upData("file_path").LastIndexOf("\") + 1))
post.Add("fileKey", encFileKey)
post.Add("userFileKeyList", userFileKeyList)
dataBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(post, Formatting.Indented))
httpWebRequest.ContentLength = dataBytes.Length
Using responseStream As Stream = httpWebRequest.GetRequestStream()
responseStream.Write(dataBytes, 0, dataBytes.Length)
End Using
httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
Using streamResponse As Stream = httpResponse.GetResponseStream
Dim str As New StreamReader(streamResponse)
responseFromServer = str.ReadToEnd()
End Using
```Kind regards
-
Hello Andreas!
I fixed Upload as you said month ago, and now it looks like you have posted:
Dim fileKey = Crypto.GenerateFileKey()
Dim uploadedFileAsByteArray As Byte() = Nothing
Dim test = GetUserPublicAndPrivateKeypair(apiUrl.Remove(apiUrl.IndexOf("api/")) & "api/v4/user/account/keypair", userPWD, token)
Dim test2 = JsonConvert.DeserializeObject(test)
Dim userKeyPair As New Dracoon.Crypto.Sdk.Model.UserKeyPair
userKeyPair.UserPrivateKey = New UserPrivateKey
userKeyPair.UserPrivateKey.PrivateKey = test2("privateKeyContainer")("privateKey")
userKeyPair.UserPrivateKey.Version = test2("privateKeyContainer")("version")
userKeyPair.UserPublicKey = New UserPublicKey
userKeyPair.UserPublicKey.PublicKey = test2("publicKeyContainer")("publicKey")
userKeyPair.UserPublicKey.Version = test2("publicKeyContainer")("version")
If Not Crypto.CheckUserKeyPair(userKeyPair, userPWD) Then
Throw New Exception("Invalid user password!")
Exit Function
End If
Dim encFileKey = Nothing
Dim timeStamp As DateTime = Now()
Dim encryptedFilePath As String = System.IO.Path.GetTempPath & timeStamp.ToFileTime.ToString & upData("file_path").Substring(upData("file_path").LastIndexOf("\") + 1)
Using wc As New System.Net.WebClient()
wc.Headers.Add("X-Sds-Auth-Token", token)
Dim data() As Byte = File.ReadAllBytes(upData("file_path"))
File.WriteAllBytes(encryptedFilePath, data)
Dim uploadedEncryptedFileAsByteArray As Byte() = RDXCryptoHelper.EncryptData(fileKey, data)
encFileKey = Crypto.EncryptFileKey(fileKey, userKeyPair.UserPublicKey)
uploadedFileAsByteArray = wc.UploadFile(apiUrl, encryptedFilePath)
End Using
Dim dataBytes As Byte() = Nothing
Dim json As Object
httpWebRequest.Method = "PUT"
httpWebRequest.ContentType = "application/json"
httpWebRequest.Headers.Add("X-Sds-Auth-Token:" & token)
Dim userFileKeyList As New Dictionary(Of String, Object)
Dim userFileKeyListItemsItem As New Dictionary(Of String, Object)
userFileKeyListItemsItem.Add("userId", userID)
userFileKeyListItemsItem.Add("fileKey", encFileKey)
Dim userFileKeyListItemsItemAsObject As New List(Of Object)
userFileKeyListItemsItemAsObject.Add(userFileKeyListItemsItem)
userFileKeyList.Add("items", userFileKeyListItemsItemAsObject)
Dim post As New Dictionary(Of String, Object)
post.Add("resolutionStrategy", "overwrite")
post.Add("keepShareLinks", True)
post.Add("fileName", upData("file_path").Substring(upData("file_path").LastIndexOf("\") + 1))
post.Add("fileKey", encFileKey)
post.Add("userFileKeyList", userFileKeyList)
dataBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(post, Formatting.Indented))
httpWebRequest.ContentLength = dataBytes.Length
Using responseStream As Stream = httpWebRequest.GetRequestStream()
responseStream.Write(dataBytes, 0, dataBytes.Length)
End Using
httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
Using streamResponse As Stream = httpResponse.GetResponseStream
Dim str As New StreamReader(streamResponse)
responseFromServer = str.ReadToEnd()
End Using
Public Function GetUserPublicAndPrivateKeypair(ByVal apiUrl As String, ByVal encryptionPass As String, token As String) As Object Implements IRDXBLL.GetUserPublicAndPrivateKeypair
Try
Dim postData As New Dictionary(Of String, Object)
postData.Add("X-Sds-Auth-Token:", token)
Dim _accountKeyPair = GetJsonResponse(apiUrl, "GET", postData)
Return _accountKeyPair
Catch fEx As FaultException(Of ErrorMessage)
Dim ErrorMessage As New ErrorMessage
ErrorMessage.Message = fEx.Detail.Message
ErrorMessage.Description = fEx.Detail.Description
'Throw New FaultException(Of ErrorMessage)(ErrorMessage)
Throw New Exception(ErrorMessage.Message)
Catch ex As Exception
Dim _ErroMessage As New ErrorMessage
_ErroMessage.Message = "Error in GetUserInfo zone: " & ex.Message
_ErroMessage.Description = "Error in GetUserInfo zone: " & ex.Message
Throw New Exception(_ErroMessage.Message)
End Try
End Function -
And here is the download code:
Dim localTempFile As String = System.IO.Path.GetTempPath & timeStamp.ToFileTime.ToString & "_" & file
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12
Dim httpWebRequest As HttpWebRequest = DirectCast(HttpWebRequest.Create(New Uri(url)), HttpWebRequest)
Dim httpResponse As HttpWebResponse
httpWebRequest.Method = "GET"
httpWebRequest.Headers.Add("X-Sds-Auth-Token:" & token)
httpWebRequest.Timeout = 600000
httpWebRequest.Accept = "application/octet-stream"
httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
Dim userKeyPair = Nothing
Dim userPass As String = Nothing
Using streamResponse As Stream = httpResponse.GetResponseStream
Using fs As New FileStream(localTempFile, FileMode.Create, FileAccess.Write)
'Need to decript here
Dim tBLL As SR_RDX.RDXBLLClient = GetRDXLayer()
If isFileEncripted Then
frmEncription = New RDXEncryption(_Parameter)
frmEncription.formOpenDocument = Me.formOpenDocument
frmEncription.frmRDX = Me
frmEncription.txt_encriptionPWD2.Hide()
Dim result As DialogResult = frmEncription.ShowDialog()
If result = DialogResult.OK Then
userPass = frmEncription.txt_encriptionPWD1.Text
Dim tBLL1 As SR_RDX.RDXBLLClient = GetRDXLayer()
Dim accountKeyPair = JsonConvert.DeserializeObject(tBLL1.GetUserPublicAndPrivateKeypair(apiRoot & "user/account/keypair", userPass, token))
UtilityForm.CloseWcfClient(tBLL1)
Dim upk As New Model.UserPublicKey()
upk.PublicKey = accountKeyPair("publicKeyContainer")("publicKey")
upk.Version = accountKeyPair("publicKeyContainer")("version")
Dim upp As New Model.UserPrivateKey()
upp.PrivateKey = accountKeyPair("privateKeyContainer")("privateKey")
upp.Version = accountKeyPair("privateKeyContainer")("version")
userKeyPair = New Model.UserKeyPair()
userKeyPair.UserPrivateKey = upp
userKeyPair.UserPublicKey = upk
If Not Crypto.CheckUserKeyPair(userKeyPair, userPass) Then
Throw New Exception("Invalid user password!")
End If
End If
End If
Dim fileID = url.Substring(url.LastIndexOf("files/") + 6).Split("/")(0)
Dim postData As New Dictionary(Of String, Object)
postData.Add("X-Sds-Auth-Token:", token)
Dim userFileKey = JsonConvert.DeserializeObject(tBLL.GetJsonResponse(apiRoot & "nodes/files/" & fileID & "/user_file_key", "GET", postData, Nothing, Nothing, Nothing))
Dim encryptedFKFromRDX As Model.EncryptedFileKey = New Model.EncryptedFileKey()
encryptedFKFromRDX.iv = userFileKey("iv")
encryptedFKFromRDX.key = userFileKey("key")
encryptedFKFromRDX.tag = userFileKey("tag")
encryptedFKFromRDX.version = userFileKey("version")
Dim dataBytesEncrypted As Byte() = Nothing
streamResponse.CopyTo(fs)
streamResponse.Close()
fs.Flush()
fs.Close()
Dim data() As Byte = System.IO.File.ReadAllBytes(fs.Name)
Dim decFileKey_2 = Crypto.DecryptFileKey(encryptedFKFromRDX, userKeyPair.UserPrivateKey, userPass, True)
Dim uploadedEncryptedFileAsByteArray As Byte() = RDXCryptoHelper.DecryptData(decFileKey_2, data)
System.IO.File.WriteAllBytes(localTempFile, uploadedEncryptedFileAsByteArray)
End Using
End Using -
Hello Vladimirs,
I do not fully understand what you do there (it seems that you write the "data" (unencrypted bytes) to the temp file and not the "uploadedEncryptedFileAsByteArray"):
Using wc As New System.Net.WebClient()
wc.Headers.Add("X-Sds-Auth-Token", token)
Dim data() As Byte = File.ReadAllBytes(upData("file_path"))
File.WriteAllBytes(encryptedFilePath, data)
Dim uploadedEncryptedFileAsByteArray As Byte() = RDXCryptoHelper.EncryptData(fileKey, data)
encFileKey = Crypto.EncryptFileKey(fileKey, userKeyPair.UserPublicKey)
uploadedFileAsByteArray = wc.UploadFile(apiUrl, encryptedFilePath)
End UsingWhat does the "RDXCryptoHelper.EncryptData(fileKey, data)" do?
Kind regards
-
Hello Andreas.
EncryptData have same code as in github example => https://github.com/dracoon/dracoon-csharp-crypto-sdk/blob/master/DracoonCryptoSdkExample/Program.cs
-
Hello Andreas!
I have one more question about "missingFileKeys" from API
how it works?
What I'm doing now:
1 - I get from server response with missingFileKeys2 - I get user/account/keypair for current account which uploaded files;
3 - Then I got "fileKeyContainer" (is it encrypted?) from ServerRespons;
4 - Then I decript those file key with MY PrivateKey
5 - Then I encrypt key with userPublicKey what I got from "missingFileKey" endpoint
6 - Then I send it to this endpoint => "nodes/files/keys"
When I try to download file from another account, I got error about wrong decryption password.... but when I check the FileKey in browser I see fileKeys which I have been sending in step 6....
So what I'm doing wrong?
-
Hello Vladimirs,
In the following you can see the implemenation of "missingFileKeys" for our C# SDK:
```
public void GenerateMissingFileKeys(long? nodeId = null, int limit = int.MaxValue) {
client.RequestExecutor.CheckApiServerVersion();
#region Parameter Validation
nodeId.MustPositive(nameof(nodeId));
limit.MustPositive(nameof(limit));
#endregion
UserKeyPair userKeyPair = client.AccountImpl.GetAndCheckUserKeyPair();
int currentBatchOffset = 0;
int batchLimit = 10;
while (currentBatchOffset < limit) {
RestRequest currentBatchRequest = client.RequestBuilder.GetMissingFileKeys(nodeId, batchLimit, currentBatchOffset);
ApiMissingFileKeys missingFileKeys = client.RequestExecutor.DoSyncApiCall<ApiMissingFileKeys>(currentBatchRequest, DracoonRequestExecuter.RequestType.GetMissingFileKeys);
HandlePendingMissingFileKeys(missingFileKeys, userKeyPair.UserPrivateKey);
currentBatchOffset += missingFileKeys.Items.Count;
if (missingFileKeys == null || missingFileKeys.Items.Count < batchLimit) {
break;
}
}
}
private void HandlePendingMissingFileKeys(ApiMissingFileKeys missingFileKeys, UserPrivateKey thisUserPrivateKey) {
if (missingFileKeys == null || missingFileKeys.Items.Count == 0) {
return;
}
Dictionary<long, UserPublicKey> userPublicKeys = UserMapper.ConvertApiUserIdPublicKeys(missingFileKeys.UserPublicKey);
Dictionary<long, PlainFileKey> plainFileKeys = GeneratePlainFileKeyMap(missingFileKeys.FileKeys, thisUserPrivateKey);
ApiSetUserFileKeysRequest setUserFileKeysRequest = new ApiSetUserFileKeysRequest {
Items = new List<ApiSetUserFileKey>(missingFileKeys.UserPublicKey.Count)
};
foreach (ApiUserIdFileId currentMissingFileKey in missingFileKeys.Items) {
UserPublicKey currentUsersPublicKey = userPublicKeys[currentMissingFileKey.UserId];
PlainFileKey currentPlainFileKey = plainFileKeys[currentMissingFileKey.FileId];
EncryptedFileKey currentEncryptedFileKey = EncryptFileKey(currentPlainFileKey, currentUsersPublicKey, currentMissingFileKey.FileId);
ApiSetUserFileKey newRequestEntry = new ApiSetUserFileKey {
FileId = currentMissingFileKey.FileId,
UserId = currentMissingFileKey.UserId,
FileKey = FileMapper.ToApiFileKey(currentEncryptedFileKey)
};
setUserFileKeysRequest.Items.Add(newRequestEntry);
}
RestRequest restRequest = client.RequestBuilder.PostMissingFileKeys(setUserFileKeysRequest);
client.RequestExecutor.DoSyncApiCall<VoidResponse>(restRequest, DracoonRequestExecuter.RequestType.PostMissingFileKeys);
}
private Dictionary<long, PlainFileKey> GeneratePlainFileKeyMap(List<ApiFileIdFileKey> fileIdFileKeys, UserPrivateKey thisUserPrivateKey) {
Dictionary<long, PlainFileKey> plainFileKeys = new Dictionary<long, PlainFileKey>(fileIdFileKeys.Count);
foreach (ApiFileIdFileKey currentEncryptedFileKey in fileIdFileKeys) {
EncryptedFileKey encryptedFileKey = FileMapper.FromApiFileKey(currentEncryptedFileKey.FileKeyContainer);
PlainFileKey decryptedFileKey = DecryptFileKey(encryptedFileKey, thisUserPrivateKey, currentEncryptedFileKey.FileId);
plainFileKeys.Add(currentEncryptedFileKey.FileId, decryptedFileKey);
}
return plainFileKeys;
}
internal EncryptedFileKey EncryptFileKey(PlainFileKey plainFileKey, UserPublicKey userPublicKey, long? nodeId = null) {
try {
return Crypto.Sdk.Crypto.EncryptFileKey(plainFileKey, userPublicKey);
} catch (CryptoException ce) {
string message = "Encryption file key for node " + (nodeId.HasValue ? nodeId.Value.ToString() : "NULL") + " failed with " + ce.Message;
client.Log.Debug(LOGTAG, message);
throw new DracoonCryptoException(CryptoErrorMapper.ParseCause(ce));
}
}
internal PlainFileKey DecryptFileKey(EncryptedFileKey encryptedFileKey, UserPrivateKey userPrivateKey, long? nodeId = null) {
try {
return Crypto.Sdk.Crypto.DecryptFileKey(encryptedFileKey, userPrivateKey, client.EncryptionPassword);
} catch (CryptoException ce) {
string message = "Decryption file key for node " + (nodeId.HasValue ? nodeId.Value.ToString() : "NULL") + " failed with " + ce.Message;
client.Log.Debug(LOGTAG, message);
throw new DracoonCryptoException(CryptoErrorMapper.ParseCause(ce), ce);
}
}
```(https://github.com/dracoon/dracoon-csharp-sdk/blob/master/DracoonSdk/SdkInternal/DracoonNodesImpl.cs)
Compare it and you will possibly find where the problem in your code is.
Kind regards,
Andreas
Bitte melden Sie sich an, um einen Kommentar zu hinterlassen.
Kommentare
19 Kommentare