-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SecretStream Push method #11
Comments
Sorry for the late reply! I think you might not be using the dart stream interface correctly. It should look something like this: final source = sourceFile.openRead();
final sink = targetFile.openWrite();
final key = _sodium.crypto.secretStream.keygen();
await source
.map<Uint8List>((chunk) => Uint8List.fromList(chunk))
.transform(_sodium.crypto.secretStream.createPush(key))
.pipe(sink); This will use the stream transformation APIs to completely pipe all data through the stream encryption into the output file. Using listen directly will sometimes cause problems, as you need to manually take care of when to wait for and close certain streams. The transformation APIs handle all that logic for you. Decryption works the same way, just use secretStream.createPull instead. |
Thanks again for your help! I'll try that and will report (and close the issue). |
Unfortunately, it doesn't work. The message is:
openWrite is of type IOSink, but pipe expects StreamConsumer. Do you have an idea how to proceed? Thanks a lot! |
Finally found it - the stream needs to be casted before calling pipe on it: Thanks a lot! |
Now decryption is not working :( - sorry:
Error message is: I just changed from createPush to createPull - code is the same like for encryption. Is this wrong? 120 bytes is the full size of the encrypted file. |
Okay, so the casting is correct, yes. I forgot about that, sorry. Regarding the decryption: I looked in the documentation again and it seems that the cipher expects predefined message "packages". In other words, if you encrypt 100 bytes at once and get, for example 128 encrypted bytes, you must pass these exact 128 bytes as complete "block" back to the decryption - this means streaming the file like that will not work. You have 2 options now:
To transform the stream into such blocks, you could use something like final source = sourceFile.openRead()
.expand(bytes => bytes)
.buffer(100); |
Ok, thanks a lot for pointing me to the right direction. I now use for encryption:
and for decryption:
but unfortunately, it still says: Any further ideas? Thanks a lot for your help! |
okay so I read a little further, and apparently the encryption stream always starts with a 24 byte header, followed by the encrypted data. so, what you have to do is something like that: var counter = 0;
var headerSent = false;
final source = sourceFile.openRead()
.expand((bytes) => bytes)
.bufferTest((e) {
counter++;
if (!headerSent && counter == _sodium.crypto.secretStream.headerBytes) {
counter = 0;
headerSent = true;
return true;
} else if (headerSent && counter == 100 + _sodium.crypto.secretStream.aBytes) {
counter = 0;
return true;
}
return false;
}); This would collect 24 bytes for the header once and the always a chunk of encrypted data. Sorry for not beeing much of a help, but I only wrapped the APIs for dart, so I don't no all of their behaviours in every detail |
Really thanks for your help - your code correctly create a stream with a header and the cipher data. However, I now get |
Hi. These errors happen if a sodium operation returns -1 - the underlying library does not provide any other error codes for security reasons, so no, there is no way to get any more details. However, if you can get the stacktrace of the unhandeled exception, at least I could figure out which operation fails. |
Hi, I got it working finally. Seems like I did something wrong with the streams. For everyone coming here having the same question, here is an example:
Thanks a lot for your help, @Skycoder42 ! |
Hello, I have modified the code from @cremfert to suit my need of chunking files to be able to cover different file sizes and the Encryption works perfectly. The Decryption also works and I am able to retrieve the original content of the file; however, there is a nagging error at the end of it (in spite of successful decryption). The error is get is:
If I do not include the If I comment out the last line Does anyone has any pointer so I can look? I am not sure if I should just ignore the exception as it might lead to memory leaks if the stream is not properly closed. Any help would be awesome! Thanks and cheers! |
I just have a question: from my understanding of the docs, the provided push method of the SecretStream API handles all the tag and header creation and ordering, right? So, instead of deciding for each chunk whether this is a final message or not (and hence set the respective tag), I only have to provide a stream of Uint8List, right? Or is there anything else I need to consider? I'm trying to implement this: https://libsodium.gitbook.io/doc/secret-key_cryptography/secretstream#example-stream-encryption
Thanks a lot!
EDIT:
I tried:
but I always receive:
Unhandled Exception: cipher stream was closed before the final push message was received
.What do I wrong?
The text was updated successfully, but these errors were encountered: