Recent Posts

Simple QR Code Generator: A Lightweight, Browser-Based Tool

March 07, 2025

Today, I’m sharing a simple yet effective tool I’ve developed: a browser-based QR Code Generator. In an era where QR codes have become ubiquitous, having a quick, reliable, and privacy-focused way to generate them is essential.

Why Another QR Code Generator?

While there are numerous QR code generators available online, I wanted to create one that is:

  • Completely client-side with no server dependencies
  • Privacy-focused (no data collection or tracking)
  • Lightning fast and responsive
  • Simple and straightforward to use
  • Free from ads and distractions

Features

The tool offers essential QR code generation capabilities:

  1. Text/URL Input: Generate QR codes for any text or URL
  2. Customizable Size: Adjust the QR code size to your needs
  3. Instant Generation: See QR codes generated in real-time
  4. Download Option: Save generated QR codes as PNG images
  5. Mobile Friendly: Works perfectly on both desktop and mobile devices

How to Use

The interface is intentionally minimalist:

  1. Visit https://static.sanjaysingh.net/qrcode/
  2. Enter your text or URL in the input field
  3. Adjust the size if needed (default size works for most cases)
  4. Click “Generate QR Code”
  5. Use “Download QR Code” to save the image

Technical Implementation

The tool is built with simplicity and performance in mind:

// Core technologies used:
- Pure HTML5 and JavaScript
- QRCode.js library for QR generation
- CSS for minimal, clean styling

Key technical features:

  • No external dependencies beyond the QR code library
  • Completely static deployment
  • No backend required
  • Cross-browser compatible
  • Mobile-responsive design

Privacy and Security

Privacy was a key consideration in the design:

  • No Data Storage: All QR code generation happens in your browser
  • No Analytics: No tracking or usage monitoring
  • No External Calls: Besides loading the page, no network requests are made
  • Open Source: Code is available on GitHub for review

Use Cases

This tool is perfect for:

  1. Business Users:
    • Creating QR codes for business cards
    • Adding QR codes to marketing materials
    • Generating quick links for presentations
  2. Personal Use:
    • Sharing Wi-Fi credentials
    • Creating quick links to social profiles
    • Generating contact information QR codes
  3. Developers:
    • Quick testing of QR code implementations
    • Generating QR codes for documentation
    • Creating QR codes for app testing

Benefits

  1. Speed and Efficiency:
    • Instant QR code generation
    • No page reloads needed
    • Quick download option
  2. Accessibility:
    • Works on any device with a browser
    • No installation required
    • Simple, intuitive interface
  3. Privacy:
    • No data collection
    • No account needed
    • No cookies or tracking

Future Enhancements

While keeping the tool simple, I’m considering adding:

  • Color customization options
  • Error correction level selection
  • SVG export format
  • QR code scanning capability
  • Batch generation feature

Try It Out

You can access the QR Code Generator at: https://static.sanjaysingh.net/qrcode/

The source code is available on GitHub

Contributing

As with all my tools, this QR code generator is open source. Feel free to:

  • Report issues
  • Suggest improvements
  • Submit pull requests
  • Share your use cases

Browser-Based Ethereum Wallet for Testing

March 05, 2025

I’ve developed: a browser-based Ethereum wallet specifically designed for testing purposes. While there are many Ethereum wallets available, I created this one with a specific focus on ease of access by making it accessible directly from the browser.

Why Another Ethereum Wallet?

During blockchain development and testing, I often found myself needing a lightweight wallet that:

  • Works directly in the browser without installation
  • Supports multiple networks (including testnets)
  • Doesn’t store any sensitive data
  • No server side and connects directly with RPC that you specify
  • Is completely transparent in its operations

Security-First Design

The wallet is built with several security principles in mind:

  1. No Server-Side Storage: All wallet operations happen entirely in your browser
  2. No External Dependencies: The wallet runs as a static site with minimal dependencies
  3. Transparent Code: The entire source code is available on GitHub
  4. Ephemeral Storage: Keys are never saved between sessions

Key Features

The wallet includes essential features needed for testing:

  • Custom RPC Endpoint Support: Connect to any Ethereum-compatible network
  • Seed Phrase/Private Key Import: Easily import test accounts
  • New Wallet Generation: Generate fresh wallets for testing
  • Native Token Support: Send and receive network native tokens
  • ERC20 Token Support: Interact with token contracts
  • Gas Estimation: Built-in gas cost estimation with safety buffer
  • Balance Checking: Real-time balance updates

How to Use

  1. Visit https://static.sanjaysingh.net/ethwallet/
  2. Enter your RPC endpoint
  3. Either:
    • Generate a new wallet for testing
    • Import an existing wallet using seed phrase or private key
  4. Start interacting with the blockchain

Important Security Notes

While the wallet is designed with security in mind, please note:

⚠️ This is a TESTING tool only. Do not use it with real funds.

  • Always use test accounts and test networks
  • Never enter production private keys or seed phrases
  • The wallet is intended for development and testing purposes only

Use Cases

This wallet is particularly useful for:

  1. Developers:
    • Testing smart contracts
    • Debugging transactions
    • Quick network interactions
  2. QA Teams:
    • Validating blockchain applications
    • Testing different network configurations
    • Verifying transaction flows
  3. Learning:
    • Understanding wallet operations
    • Exploring blockchain interactions
    • Studying Web3 development

Try It Out

You can access the wallet at https://static.sanjaysingh.net/ethwallet/

The source code is available on GitHub

Feedback Welcome

As this is a tool for the developer community, I welcome:

  • Bug reports
  • Feature suggestions
  • Security improvement ideas
  • General feedback

Feel free to open issues or submit pull requests on GitHub.

Remember: This is a testing tool. Always use appropriate security measures when dealing with real cryptocurrency transactions.

AAD JWT Token Generator: A Web-Based Azure AD Token Generation Tool

March 05, 2025

I’m excited to share a new tool I’ve developed called AAD JWT Token Generator, a web-based application designed to simplify the process of generating JWT tokens from Azure AD. Whether you’re a developer testing Azure AD-protected APIs or an administrator verifying token claims, this tool makes the token generation process straightforward and efficient.

Why I Built This Tool

Working with Azure AD-protected services often requires generating and testing JWT tokens. While there are various ways to obtain these tokens, I found myself wanting a more streamlined solution that could:

  1. Provide a clean, modern web interface
  2. Support both GUI and command-line usage
  3. Be easily deployable anywhere
  4. Work without storing sensitive credentials

Key Features

The AAD JWT Token Generator comes with several powerful features:

  • Modern Web Interface: Built with Vue.js and styled with Tailwind CSS for a clean, professional look
  • Flexible Token Generation: Customize your tokens with various parameters
  • Headless Mode: Generate tokens via command line without launching the web interface
  • Docker Support: Easy deployment using containers
  • Single Binary: All frontend assets are embedded for simple distribution

How to Use It

Web Interface

The web interface is the easiest way to get started. Simply:

  1. Run the application (either directly or via Docker)
  2. Navigate to http://localhost:5555
  3. Enter your Azure AD credentials:
    • Client ID
    • Tenant ID
    • Client Secret
    • Scope (optional)
  4. Click “Generate Token”

Command Line

For automation scenarios, use the headless mode:

aad-jwt-gen -headless \
  -clientId="your_client_id" \
  -tenantId="your_tenant_id" \
  -clientSecret="your_client_secret" \
  -scope="your_scope"

Docker Deployment

If you prefer using Docker:

docker pull sanjaysingh/aad-jwt-gen
docker run -p 5555:5555 sanjaysingh/aad-jwt-gen

Technical Details

The tool is built with:

  • Backend: Go 1.21.0+
  • Frontend: Vue.js with Tailwind CSS
  • Containerization: Docker
  • Architecture: Client-server with embedded static files

Getting Started

Installation

Choose your preferred installation method:

Using Go:

go install github.com/sanjaysingh/aad-jwt-gen@latest

Using Docker:

docker pull sanjaysingh/aad-jwt-gen

Security Considerations

The tool is designed with security in mind:

  • No credential storage
  • All processing happens locally
  • Direct communication with Azure AD
  • No logging of sensitive information

Contributing

The project is open source and contributions are welcome! Feel free to:

  • Report issues
  • Suggest features
  • Submit pull requests
  • Share your use cases

You can find the project on GitHub.

Conclusion

The AAD JWT Token Generator aims to simplify Azure AD token generation for developers and administrators. Whether you’re testing APIs, debugging token issues, or automating authentication workflows, I hope this tool makes your work easier.

Try it out and let me know what you think! Your feedback will help shape future improvements.

Migrating from Blogger to Jekyll/Github Pages

March 03, 2025

I recently migrated my blog from Blogger to Github Pages. I’ve created a Docker-based migration tool that makes this process seamless and efficient. Let me introduce you to the Blogger to Jekyll Migration Tool. Note that Jekyll is used by Github Pages so once you have migrated to Jekyll, you can commit that to a repo and Github Pages will serve that just like a Jekyll server.

Why Migrate from Blogger to Jekyll?

Blogger has been a reliable platform for many years, but static site generators like Jekyll offer several advantages. Github pages also allows to own the contents and you have full control over the blogs you publish.

  • Better performance and faster load times
  • More control over your site’s design and functionality
  • No dependency on Google’s services
  • Free hosting options like GitHub Pages
  • Better SEO capabilities
  • Modern development workflow

Features of the Migration Tool

The tool I’ve developed handles the entire migration process automatically:

  • Converts Blogger posts to Jekyll format
  • Downloads and localizes all images from your posts
  • Organizes content by year and month
  • Preserves post metadata and categories
  • Converts HTML content to clean Markdown
  • Sets up a modern, responsive theme (Minimal Mistakes)

How It Works

The migration process is containerized using Docker, ensuring a consistent environment across different operating systems. Here’s what happens under the hood:

  1. The tool processes your Blogger XML export
  2. Downloads and optimizes all images
  3. Converts HTML content to Markdown
  4. Organizes posts chronologically
  5. Sets up a complete Jekyll site structure

Getting Started

The migration process is straightforward:

# 1. Place your Blogger XML export in the project directory
# 2. Run the migration
docker-compose up

# 3. Your new Jekyll site will be ready in the migrated-blog-server directory and you can run it from there.

cd migrated-blog-server
bundle exec jekyll serve

Customization Options

After migration, you can easily customize your new Jekyll site:

  • Modify the _config.yml file for site-wide settings
  • Customize the Minimal Mistakes theme
  • Add your own CSS and JavaScript
  • Configure SEO settings
  • Set up analytics

Try It Out

The project is open source and available on GitHub. You can use the included sample blog XML to test the migration process before using it with your own blog.

AspNet Core: Appsettings from environment variables gotcha

July 04, 2017

Changes to environment variables are not refreshed until you restart the Visual Studio. This can be frustrating if you make some change and expect it to reflect in the application.

This is not new to AspNet core but rather a generic Visual Studio (or any Windows Process for that matter) behavior but it is more visible in the AspNet core because Environment Variables configuration is initialized by default and it is easy to forget the gotcha of restarting. Re-running the application does not help.

.Net Core - Hello World from command line

May 21, 2016

.Net Core is now RC2 and is hopefully going to be stable and not see major changes. Some very basic developmental structural changes happened across RC1 and RC2 so this is never guaranteed though. RC2 has much cleaner and consistent (with other programming languages) development experience which usually is something like following.

  1. Download and install the language
  2. Create a program
  3. Compile and run it

You can follow these steps below to get up and running with your first .Net core Hello World project.

  1. Download and install .Net core from https://www.microsoft.com/net/core#windows
  2. Open command prompt and create a new directory and ‘cd’ to that directory
  3. Create a new .Net core project in the ‘newproject’ directory that we created above.
  4. Restore all the dependencies for the project
  5. Compile and run

That is all. You have your first .Net Core Hello World! program up and running.

I have created a chocolatey pacage so that .Net core SDK can be installed from command like itself. This package is located here.

With chocolatey, the steps then become as follows.

  1. Install .Net core. Note the -pre that is required because it is a prelease version of .net core. It will install latest .Net core which is RC2 as of this post. This installs .net core and updates the PATH so that ‘dotnet’ command is available from the command prompt.
  2. Refresh PATH for current command prompt session. Chocolatey comes up with pretty neat command for this.
  3. Create a new project directory and go to that directory
  4. Create new project
  5. Restore all the dependencies for the project
  6. Compile and run

That’s it. You have a.net core application running while never had to leave the command prompt.

RabbitMQ Connection String Gotcha

May 01, 2016

RabbitMQ connection strings looks like following

amqp://username:[email protected]/myvhost

or for amqp over SSL/TLS it looks like following

amqps://username:[email protected]/myvhost

One very important thing to always keep in mind is that username, password and vhost should be pct-encoded. If the password, for example, is #asd49d$ then the amqp connection string will become as follows-

amqp://username:%23asd49d%[email protected]/myvhost

It is very well documented here.

Secure Web Application Practices - Account Management

March 21, 2016

In this post, I am going to cover some of the best practices around account management. Account Management covers things like ‘account registration’, ‘forget password’, ‘remember me’, ‘password storage’, etc.

Following are account management practices that one should consider to minimize the risk of breach.

  • **Password Storage: **Always use cryptographically strong password hashing (not encryption) to store passwords. There are only a few cases you want to store password in encrypted (and not hashed) format. Always use some random credential-specific salt with the hashing algorithm you are using. This makes the hashes non-predictable and hard to reverse even if you are using simple algorithms like MD5. For the hashing algorithm, prefer from one of the followings (in the order of preference):

  • Argon2

  • PBKDF2 

  • scrypt

  • bcrypt 

**     https://www.owasp.org/index.php/Password_Storage_Cheat_Sheet 

  • Registration: **

  • There are pros and cons to whether to use email address or free text username for the login id. While there is privacy concern for the use of email, requiring a different username is a little bit of inconvenience on the user end. Some sites do allow both which is a better option because it leaves the option in the user’s hand.

  • Require strong password with a mix of alphanumeric and special characters. Do not limit users with use of any special characters as much as possible. Always have a limit of the minimum length of the password. It is always better to have a very high maximum limit on the length of the passwords. It allows for people to use pass phrases and use super strong passwords. If one is using any password manager, then length of the password does not matter anyway because you don’t have to remember it. 

  • Do not disable pasting of password from clipboard. There is almost no valid reason to disallow users from pasting a password. It in fact discourages users to select a strong password, particularly when you use some kind of password manager to generate a strong password first and then want to use that.

  • Verify account via email. Always require the user to verify the account by sending some email to their account and then requiring them to verifying by going to some auto generated unique link. This prevents spammers and also ensure authenticity of the user. You don’t want somebody else registering using your email address!

  • Protect against account enumeration. Do not disclose the existence of a user account. Always throw a generic message that do not disclose whether or not the user being registered exists or not. While in some cases it might be a privacy concern because somebody can find if you are registered in a dating site for instance, in other cases it might be used for a brute force attacks.

  • Use CAPTCHA for anti automation. It is very easy to automate Http requests to a website and that is true for automate the registration using some common names and flood the server. Use of CAPTCHA will protect against this kind of attacks.

Logon:

  • Protect against account enumeration attacks. You should not disclose existence of a user account in the login error messages. ”Login for User foo: invalid password”, ”Login failed, invalid user ID”, ”Login failed; account disabled”, ”Login failed; this user is not active” are bad messages. The correct message would be ”Login failed; Invalid userID or password” irrespective of whether password is incorrect or the userid is not registered.

  • https://www.owasp.org/index.php/Authentication_Cheat_Sheet

Protect against brute force: Use CAPTCHA to prevent automated logins. Also, have some minimum duration between two login attempts. For instance, do not allow login request if last login attempt was less than 30 seconds away. The idea is to introduce some kind of limit or delay when you see brute force kind of attack on the server. Employ two-factor authentication: This option can be employed optionally to better secure the user login. In the mechanism, you use user’s phone or secondary email address to send a temporary one time password that you require before they can login. This adds little bit of inconvenience to the user but can optionally be provided for users so that they can selectivity opt in.

Remember Me:

  • The first choice will be to see if you can live without this feature. Remember Me is usually not a good option for high value applications. For this reason you don’t see remember me feature on bank websites.

  • Use a specific Secure HttpOnly cookie for Remember Me. Do not store username/password in the cookie. 

  • Set cookie expiry to be as minimal as you can afford for your application. 

  • Require user to re-authenticate before they can perform any sensitive operation. For instance, ask user to provide ‘old password’  when they try to change their password.

Password Reset:

  • Do not send password in the email. That is true for both when registering a new user or when resetting password. Emails are unsafe and usually lie in unencrypted form on the servers.

  • Use time limited reset token. Generate a link to send this to user to the registered email and they have to click on this link to set the new password. Link should expire after the first use or when the validity time period (should be very less, may be an hour) has expired.

  • Use security questions. This is another approach that can be taken to verify authenticity of the user before you allow them to change the password.

Log Off:

  • Expire session on the server. See if you can keep some kind of expiry for user sessions. For instance, it might be reasonable to log off user after 20 minutes of inactivity. As with everything else, it depends on the nature of the site. It might be inconvenience of some sites, like social media sites for instance.

  • Protect against CSRF. As with Login and other forms, this is also a probable candidate for CSRF attacks and this should be protected against CSRF attacks.