Muscurd-i - My personal Password Manager
Tags: passwordmanager, avalonia, dotnet, githubactions
Published: 2022-09-20 14:24:13

---
title: Muscurd-i - My personal Password Manager
published: true
description: 
tags: passwordmanager, avalonia, dotnet, githubactions
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
---

Some time ago I published in here a [post](https://vikkio.hashnode.dev/my-adventures-in-desktop-gui-app-development-land) where I was speaking about me getting a bit of an idea on how to work with Desktop apps in 2022, after years of Web Development (and with a massive disgust for electron apps).

As mentioned there, one of my projects to learn more about [AvaloniaUI](https://avaloniaui.net/) and [MVVM](https://docs.avaloniaui.net/guides/basics/mvvm) was to create my own local Password Manager, here I will speak more about why and how I made it work.

### What
I got **Assasin's Creed Unity** on a steam sale this summer, and since I am quite busy with life at the moment I put it off installing it and playing it for a while. Then I did and it was shit (I wrote a review about it [here](https://yokupoku.website/reviews/assassins-creed-unity-game-pc-boring-as-expected/)).

One of the main issues I had with this game though, wasn't game related, but more of an integration bug.

When you startup up the game **Steam** asks **Ubisoft-launcher** to launch the game, so you need to log in to your **Ubisoft** account to launch it.
Sometimes it forgets your password, fine, you recover it from your saved passwords and copy-paste it.

Then you get bored of killing people while flying from rooftop to rooftop and you just quit the game.

Ubisoft forgot your password and won't save to the cloud your files.

You need to get your password again. boring.

I wish there was a local running password manager that wouldn't cost a fortune.
Oh! I am a developer, why don't I do one myself?


![thanos-infinity-gauntlet.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1663679522817/bzkSC8oJJ.gif)

I love to name my side projects with [Sicilian](https://en.wikipedia.org/wiki/Sicilian_language) terms, and since this was about me having a bad memory I called it
`Muscurd-i` which pronounced in English sounds like `m'u scurdaj` which mean 'I forgot it'.


### How
So since a new item in my toolbelt was Avalonia and Dotnet, I decided to create this app with it, so I would be able to build and run the same app on Mac, Win and Linux.

The app itself was really simple in my head:
A small 3 screens app:
**Login**, **List of Password**, Add a New Password.

The **Login** would ask you for a master password and if you managed to get it right it would show you the list of your added password that you will be able to search and copy to your clipboard.

You would also need the possibility to add a new password on the third screen.

### Security
How do you store passwords you ask?
Well, not in clear text certainly.

My main idea was this:

![pa.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1663681066133/QqskDSRUv.png)

So UI would allow to get the clear text and Encrypt when stored.

So if someone got hold of the db file (I am using [LiteDB](https://www.litedb.org/)) won't be able to use them unless they guessed the encryption key.

But how to do that?

Well, it is quite annoying to find stuff for Dotnet, a load of code you can find around is quite old and deprecated but eventually, I did find a tutorial on the new Aes Encryption Lib. And worked my way to upgrade a shitty deprecated code example on [StackOverflow](https://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string-in-c).

Producing [this](https://github.com/vikkio88/muscurd-i/blob/main/Muscurdi/Libs/Crypto.cs#L8) little static boy:
```csharp

public static class Crypto
{
    public static string Encrypt(string plainText, MasterPassword password) {}
    public static string? Decrypt(string encryptedText, MasterPassword password) {}
}
```

so I can get set and get the password from and to the database using the MasterPassword.

Funny thing is that I am using the master password as the encryption key, so it needs to be 32 Ascii characters, so I can get the right number of bytes to encrypt the string with AES.

To do that but also to avoid being a completely impossible to remember password I made it so is 4 words of 4 letters, and 4 digits, so something like
```
yoyo-baba-nana-caca-1234
```
Would be a nice master password, of course, it will be possible brute force guess it, but that is valid for everything.

## Misc

I TDD-ed both functionalities:

[Muscurdi.Tests/Models/MasterPasswordTests.cs](https://github.com/vikkio88/muscurd-i/blob/main/Muscurdi.Tests/Models/MasterPasswordTests.cs)

[Muscurdi.Tests/Libs/MasterPasswordHelperTests.cs](https://github.com/vikkio88/muscurd-i/blob/main/Muscurdi.Tests/Libs/MasterPasswordHelperTests.cs)


[Muscurdi.Tests/Libs/CryptoTests.cs](https://github.com/vikkio88/muscurd-i/blob/main/Muscurdi.Tests/Libs/CryptoTests.cs)


And after few days of playing around with Avalonia it was ready to rumble, kind of:


![187184250-3eb9643a-2e0d-43fb-9b0e-e975d8e36369.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1663681933889/t-AXT1sFg.gif)

I know if kind of looks like shit, but I improved it with loads of [CSS-like](https://github.com/vikkio88/muscurd-i/blob/main/Muscurdi/Assets/Styles/Main.xaml) and some [FontAwesome](https://www.nuget.org/packages/Projektanker.Icons.Avalonia.FontAwesome/) integration.

This last [one](https://github.com/vikkio88/muscurd-i/blob/main/Muscurdi/Views/ListView.axaml#L19) was amazing, I could see so much of HTML things I had done before:
```xml
<Button Command="{Binding GoToAdd}" Classes="IconBtn">
        <i:Icon Value="fa fa-plus" FontSize="16" />
</Button>
```

And now it looks a bit better I would say.

![newscurdai.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1663682465681/V5z_nd2U2.jpg)

As a bonus feature I added a list of 4 letter words that generates a random password for you.

Up to the user whether to use it as inspiration or complete remove it.

### Other things I learned

![masked.gif](https://raw.githubusercontent.com/AvaloniaUI/Documentation/a36f9f27970baad31859b4d40c2aeac2e22735ce/.gitbook/assets/maskedtextexample.gif)
There were no docs on the *MaskedTextBox*, only some of **WPF** so I decided to be a good boy scout and write them [myself](https://docs.avaloniaui.net/docs/controls/maskedtextbox) with [my second PR](https://github.com/AvaloniaUI/Documentation/pull/320/files) on AvaloniaDoc.

Dotnet build commands on platform that are not Windows do not always work properly.

I tried to make the app run by itself without the cli opening in the background, and on Linux didn't work, tried the same on Windows and build the app for Linux/Mac and Windows and it worked like a charm, so I decided to delegate the build process to [a GH action](https://github.com/vikkio88/muscurd-i/blob/main/.github/workflows/on-release.yml#L8).

So now every time I create a tag/release on Github I will get those bin compiled and published ready to be downloaded like [here](https://github.com/vikkio88/muscurd-i/releases/tag/alpha_220920_3):

![Screenshot 2022-09-20 at 15.12.06.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1663683135437/lmM-3MgX6.png)

Even though we do some quite heavy building and bundling and trimming, the apps unzipped are still around 90Mb, not quite big as an electron app, but still quite annoying.

### In Conclusion

I liked working on this small project and I am now looking forward to finishing another *private* secret Avalonia project I am working on.

[Here](https://github.com/vikkio88/muscurd-i) is the repo for anyone who wants to try it.

I already found a few bugs, like you can open multiple instances and I might want to add also the username not only the password, but I will get around to it whenever I have a bit more time.

until next time.