tuupola / branca-spec

Authenticated and encrypted API tokens using modern crypto
https://www.branca.io/
219 stars 7 forks source link

DotNet implementation #19

Closed tuupola closed 2 years ago

tuupola commented 5 years ago

DotNet implementation is missing. Could use xchacha-dotnet by @tom-auger as basis.

tuupola commented 4 years ago

https://github.com/thangchung/branca-dotnet

AmanAgnihotri commented 2 years ago

Hello! I recently discovered the Branca Specification and found it useful that I went ahead and created a .NET implementation of it.

I am writing in this closed issue because I went over the particular repository referenced above, the branca-dotnet, and found it to have various issues that should disqualify it from being a Branca implementation in .NET until it appropriately updates itself. Here are some of the differences between that repository and latest Branca specification:

  1. For create timestamp, branca-dotnet uses (int)DateTime.UtcNow.Ticks which simply does not return the Unix timestamp that is explicitly mentioned in the Branca Specification. This issue is not revealed because branca-dotnet also does not do anything with the create timestamp value during the decoding phase even though it accepts an optional ttl value.

  2. Both the encoding phase and decoding phase utilize the ChaCha20Poly1305 algorithm instead of the specified XChaCha20Poly1305 one. Branca Specification once specified the former algorithm and this repository was last updated some 3 years ago and considers Nonce length to be 12 bytes instead of the 24 bytes mentioned in the latest specification.

  3. branca-dotnet uses a specialized Base62 encoding scheme that does not yield the outputs that make the library interoperable with other Branca implementations that follow the specification to the point. It generates some base62 encoded string but it will not pass the test vectors that the Branca Specification has listed. This is not revealed because branca-dotnet has no tests. I ran the code to see how its base62 encoding works as it seemed efficient and figured this point out.

  4. branca-dotnet takes a string key in its Branca constructor and throws if the key length is not 32. This was brought up as a reasonable issue in #37.

  5. From a usability point of view, there exists no NuGet package for branca-dotnet.

So, I wrote an implementation of Branca. It can be found here:

https://github.com/AmanAgnihotri/Branca

I implemented all the test vectors too and my library passes all the tests:

https://github.com/AmanAgnihotri/Branca/blob/main/test/Branca.Tests/BrancaTests.cs https://github.com/AmanAgnihotri/Branca/blob/main/test/Branca.Tests/HexKeyTests.cs

The ValidTestData in BrancaTests represents 16 test vectors (8 from encoding and 8 from decoding, as they are the same). The InvalidTestData represents 8 more test vectors mentioned in the decoding phase. Finally, the last test vector concerning invalid key is mentioned in HexKeyTests. Covering all the 25 test cases and a few more.

I also put this up as a NuGet package for easier integration:

https://www.nuget.org/packages/Branca/

The library is usable at this point and I have certain roadmap planned for a streamlined integration with ASP.NET Core. I also intend to actively maintain it.

I would appreciate it if you can mention it in your repository as a library that .NET developers can use. Any feedback is also welcome.

Language Repository License Crypto library used
.NET AmanAgnihotri/Branca LGPL-3.0-or-later NaCl.Core
tuupola commented 2 years ago

I did not realise thangchung/branca-dotnet was flawed. Will add your to the list. However one note. Above you say AmanAgnihotri/Branca has LGPL licencse. In you repository both README and COPYING say it is GPL. Which one is correct? For a library LGPL is probably the better choice.

AmanAgnihotri commented 2 years ago

My implementation is licensed as LGPL-3.0-or-later. All C# files in the solution begin with the SPDX identifier accordingly to clarify this:

// SPDX-License-Identifier: LGPL-3.0-or-later // Copyright © 2021 Aman Agnihotri

The way one adds LGPL license is by adding both the COPYING file (which is the GPL license) and the COPYING.LESSER file (which is the addition to the GPL which makes it LGPL). My repository has both those files: COPYING and COPYING.LESSER.

Here's how the COPYING.LESSER file starts:

This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.

I hope that clarifies it. My implementation is LGPL licensed and as such also usable commercially without the commercial entity having to make their project FOSS unless it is a derivative of this library itself which then has to be LGPL licensed.

GitHub correctly recognizes the LGPL-3.0 license for my project as it shows it on the right-hand side which links it to the COPYING file for that is where the LGPL license actually starts. It starts with GPL and then incorporates additional permissions that are present in the COPYING.LESSER file.

image
AmanAgnihotri commented 2 years ago

I just realized that you were probably referring to the License text in the README which indeed was faulty with mention of GNU General Public License and not GNU Lesser General Public License. I have now fixed that as well so it should show just fine.

tuupola commented 2 years ago

@AmanAgnihotri Published, thanks!