<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Passwords &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/passwords/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Tue, 09 Dec 2025 16:30:33 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>New WebUserAuthentication Control: Look, Mom, No Passwords!</title>
		<link>https://blog.xojo.com/2025/12/09/new-webuserauthentication-control-look-mom-no-passwords/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Tue, 09 Dec 2025 16:30:29 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[2025r3]]></category>
		<category><![CDATA[Authentication]]></category>
		<category><![CDATA[Passkey]]></category>
		<category><![CDATA[Passwords]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15321</guid>

					<description><![CDATA[The web framework has a new control available in the Library, WebUserAuthentication. Now that Passkeys have arrived, let&#8217;s explore this feature! Passkeys Demo In this&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The web framework has a new control available in the Library, <code>WebUserAuthentication</code>. Now that Passkeys have arrived, let&#8217;s explore this feature!</p>



<h2 class="wp-block-heading">Passkeys Demo</h2>



<p>In this demo, we will be creating a new account using just our email. Using a platform authenticator, like Apple Passkeys or Windows Hello will make this pretty easy. They are integrated in the operating system and synced across devices. I will be using macOS with the integrated Passwords app, but this is supported in Windows through Windows Hello, or you could store, sync and use Passkeys using a Google Chrome Profile.</p>



<figure class="wp-block-video"><video height="1240" style="aspect-ratio: 1472 / 1240;" width="1472" controls src="https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-passwordless-signup.mp4"></video></figure>



<p>As you can see, there is no intermediate step. No need to use a separate app to store your passwords securely. A Passkey will be generated and stored in the authenticator in one simple step. This Passkey will be automatically synced across devices and available on my iPhone.</p>



<p>Opening the Password application, I already can confirm my new Passkey has been stored for &#8220;localhost&#8221;. Notice the user name is also there, meaning you won&#8217;t need to fill it during the login process.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="710" src="https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-in-password-app-1024x710.png" alt="" class="wp-image-15323" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-in-password-app-1024x710.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-in-password-app-300x208.png 300w, https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-in-password-app-768x533.png 768w, https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-in-password-app-1536x1065.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-in-password-app.png 1716w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>The username isn&#8217;t important or even required, it&#8217;s just to display a friendly name for this user. A Passkey will include the user ID, which can be any arbitrary String you want. In my example, I&#8217;ve used the new <a href="https://documentation.xojo.com/api/math/random.html#random-uuid" target="_blank" rel="noreferrer noopener">Random.UUID method</a>, but this is completely up to you. And this is transparent for the end user.</p>



<p>Now, let&#8217;s try to login:</p>



<figure class="wp-block-video"><video height="1240" style="aspect-ratio: 1472 / 1240;" width="1472" controls src="https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-passwordless-signin.mp4"></video></figure>



<p>That&#8217;s it!</p>



<p>Another thing to notice is, while I have several Passkeys for different websites, only the relevant Passkey can be used. This makes Phishing attacks useless. End users won&#8217;t be able to use a Passkey anywhere else, just on the website where it has been created. And also, users won&#8217;t be able to send their password by mistake to an attacker because … they can&#8217;t!</p>



<p>For web application developers, another interesting thing to note is that you won&#8217;t be able to store a Passkey insecurely. Even if your database gets compromised, a hacker won&#8217;t be able to use the stored public keys to authenticate those users with another service. To make it easier to understand, you will be storing a lock, not the key used to open it.</p>



<h2 class="wp-block-heading">Other User Journeys</h2>



<p>My demo is just the classic email / password sign up / sign in workflow, but without using a password. Passkeys is based on WebAuthn (part of FIDO2) and there are several ways you can use this technology in your web application. For example, you could use a shared computer and still be able to securely log in using your mobile. The platform will display a QR code you can read with your phone camera, and grant the access from your personal device.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="889" src="https://blog.xojo.com/wp-content/uploads/2025/08/Sign-In-1024x889.png" alt="" class="wp-image-15325" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/Sign-In-1024x889.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/08/Sign-In-300x260.png 300w, https://blog.xojo.com/wp-content/uploads/2025/08/Sign-In-768x666.png 768w, https://blog.xojo.com/wp-content/uploads/2025/08/Sign-In-1536x1333.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/08/Sign-In.png 1604w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>In my example application, the user can sign up using different emails. If the Passwords app encounters more than one for my domain it will allow the user to specify the Passkey to use:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="889" src="https://blog.xojo.com/wp-content/uploads/2025/08/o2-baieeamele.com_-1024x889.png" alt="" class="wp-image-15326" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/o2-baieeamele.com_-1024x889.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/08/o2-baieeamele.com_-300x260.png 300w, https://blog.xojo.com/wp-content/uploads/2025/08/o2-baieeamele.com_-768x666.png 768w, https://blog.xojo.com/wp-content/uploads/2025/08/o2-baieeamele.com_-1536x1333.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/08/o2-baieeamele.com_.png 1604w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Xojo will take care of preparing the <code>WebAuthn</code> steps, verifying signatures and doing the common busy work for you. You will have to decide which workflow makes sense for your application and perform any further verifications, like sending a verification email on register, to ensure this user owns that account.</p>



<h2 class="wp-block-heading">Multi-Factor Authentication</h2>



<p>If you already require your users to authenticate with a username (or email) and a password, you could use <code>WebUserAuthentication</code> as a second factor. That means the user will need to provide something this person knows (a username and password combination) in addition to something the user has (the authenticator device)</p>



<p>Other common multi-factor authentication schemes are email magic links and time-based one-time passwords, <em>&#8220;TOTP&#8221;</em>.</p>



<p>More factors equal better security, of course. But as usual when it comes to security, you&#8217;ll have to find the sweet spot between secure and comfortable.</p>



<h2 class="wp-block-heading">Usernameless + Passwordless Authentication … Wait, What?!?</h2>



<p><em>&#8220;How can I authenticate without providing my username or email?&#8221;</em>. This is where real new possibilities arise. When you use a username with a password that only Chuck Norris and you know, this becomes a &#8220;proof of identity&#8221; (at least in theory, in practice a hacker could compromise an account using a weak password)</p>



<p>When using an authenticator without a username or password, it becomes a &#8220;proof of possession&#8221; of the authenticator device.</p>



<p>Again, think about it as a locker&#8217;s lock and a key. Everyone can see the lock, but only people with the correct key can open it. The public key would be the door&#8217;s lock, while the authenticator device would be the key. You can share the key with another person you trust to grant this person access to the contents behind that door. The difference with a real-life lock is that we will be using a really secure one, with a security key.</p>



<p>As long as you can proof you have a valid &#8220;key&#8221; to authenticate, you are granted to continue.</p>



<p>Consider the following scenario. The company could have a web application that uses a traditional username + password authentication but, for really special activities, the user needs to authenticate with a physical USB key authenticator device that is shared by everyone in the office.</p>



<p>Other use cases are obviously when privacy is involved. A private journal, or a private blogging service, voting. The inconvenience in this case is the user won&#8217;t be able to recover the account if they lose access to the authenticator. In this case, you might want to offer a different recovery solution, like printing a very long recovery code. If they also lose the recovery code, they will permanently lose the account.</p>



<h2 class="wp-block-heading">How To Use The New Control</h2>



<p>As you do with any other non-visual control, like a <code>WebTimer</code>, you can just drop the new <code>WebUserAuthentication</code> control into your WebPage.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="491" src="https://blog.xojo.com/wp-content/uploads/2025/08/webauthentication-dropping-into-webpage-1024x491.png" alt="" class="wp-image-15327" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/webauthentication-dropping-into-webpage-1024x491.png 1024w, https://blog.xojo.com/wp-content/uploads/2025/08/webauthentication-dropping-into-webpage-300x144.png 300w, https://blog.xojo.com/wp-content/uploads/2025/08/webauthentication-dropping-into-webpage-768x368.png 768w, https://blog.xojo.com/wp-content/uploads/2025/08/webauthentication-dropping-into-webpage-1536x736.png 1536w, https://blog.xojo.com/wp-content/uploads/2025/08/webauthentication-dropping-into-webpage-2048x982.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Then configure its properties. The most important one is the Domain field. It must match the domain name where your application will be deployed. If you want to test it locally without using HTTPS, it must be &#8220;localhost&#8221; (&#8220;127.0.0.1&#8221; won&#8217;t work)</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="666" height="269" src="https://blog.xojo.com/wp-content/uploads/2025/08/Appearance-copia.png" alt="" class="wp-image-15328" srcset="https://blog.xojo.com/wp-content/uploads/2025/08/Appearance-copia.png 666w, https://blog.xojo.com/wp-content/uploads/2025/08/Appearance-copia-300x121.png 300w" sizes="auto, (max-width: 666px) 100vw, 666px" /></figure>



<p>There are four events available:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="656" height="250" src="https://blog.xojo.com/wp-content/uploads/2025/11/Captura-de-pantalla-2025-11-20-a-las-10.50.33.png" alt="" class="wp-image-15544" srcset="https://blog.xojo.com/wp-content/uploads/2025/11/Captura-de-pantalla-2025-11-20-a-las-10.50.33.png 656w, https://blog.xojo.com/wp-content/uploads/2025/11/Captura-de-pantalla-2025-11-20-a-las-10.50.33-300x114.png 300w" sizes="auto, (max-width: 656px) 100vw, 656px" /></figure>



<p>You can use <code>RegistrationSucceeded</code> and <code>AuthenticationSucceeded</code> to interact with your Database, store the details and redirect the user to their dashboard.</p>



<p>In <code>RegistrationSucceeded</code>, a <code>WebAuthenticationCredential</code> will be given to you. This is a data transfer object with the following properties you need to store in your database:</p>



<ul class="wp-block-list">
<li>ID</li>



<li>PublicKey</li>



<li>AuthenticationAttempts</li>



<li>DisplayName</li>
</ul>



<p>Error will be fired when something goes wrong. A message will also show with the details about what happened, but it isn&#8217;t meant to be shared with the end user. During the sign up and sign in processes, you should display generic messages for security, to avoid letting bad actors know what&#8217;s going on. If you need to inform the user something related to these messages, you can send them an automated email instead.</p>



<p><code>CredentialRequested</code> will be fired during the authentication ceremony. A userId and a credentialId will be given to you, and you should return a new <code>WebAuthenticationCredential</code> instance with the details coming from the <code>RegistrationSucceededEvent</code>.</p>



<p>Also, when <code>AuthenticationSucceeded</code> happens, the event will come with an <code>authenticationAttempts</code> parameter. This will be an incremental value used to update your credentials. This is part of the <code>WebAuthn</code> protocol sign in ceremony used to detect cloned authenticators, which is supported by Xojo. Please notice this value might come always as &#8220;0&#8221; when using Safari, for example, but Google Chrome will increase its value each time.</p>



<p>You can initiate a Registration or Authentication ceremony by calling Register or Authenticate, respectively.</p>



<ul class="wp-block-list">
<li><strong>Register</strong>(userId As String, username As String = &#8220;&#8221;, displayName As String = &#8220;&#8221;)<br>The parameter userId is required, the new credential will be built specifically for it. It can be anything that makes sense in your application, like an auto-incremental number or a random UUID . The other parameters are meant for giving the credential a friendly name. The username could be a nickname, or an email. In workflows where you allow the user to store more than one passkey, the displayName could be something like &#8220;Backup key&#8221;.</li>



<li><strong>Authenticate</strong>(Optional allowCredentials() As String)<br>This will initiate the authentication ceremony. You can optionally pass an array of credential IDs, allowed for the user trying to get access to the protected resource.</li>
</ul>



<h2 class="wp-block-heading">Adoption and Compatibility</h2>



<p>Not every user may know they even exist, what they are, how they work or if they will be more secure than using their pet&#8217;s name and birthdate. This can cause some friction. Other users that adopted the usage from day one might have at least two physical USB keys. They expect your application to allow them to enter more than one, just in case they lose their main USB key.</p>



<p>Passkeys are here to stay and their adoption will continue growing on web services. That said, depending on the combination of operating system and browser, there are some gotchas. Google Chrome or Firefox should work on every operating system. Apple users will probably obtain the best user experience if they&#8217;re tied to this ecosystem. Linux users using alternative browsers could experience some challenges.</p>



<p>If compatibility is a must for your application, you should still offer an alternative to Passkeys. For example, legacy passwords, or &#8220;magic login links&#8221; sent by email.</p>



<h2 class="wp-block-heading">Wrapping Up</h2>



<p>We are sure Passkeys will be the norm in the coming years. Read more in the <a href="https://documentation.xojo.com/api/web/webauthenticationcredential.html" target="_blank" rel="noreferrer noopener">Xojo Docs</a>. Xojo is ready to embrace them and you can start adopting them in your Xojo Web application today!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-passwordless-signup.mp4" length="684699" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2025/08/passkeys-passwordless-signin.mp4" length="435817" type="video/mp4" />

			</item>
		<item>
		<title>Updating macOS Keychain Passwords</title>
		<link>https://blog.xojo.com/2025/04/24/updating-macos-keychain-passwords/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 24 Apr 2025 15:00:00 +0000</pubDate>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[2025r1]]></category>
		<category><![CDATA[macOS]]></category>
		<category><![CDATA[Passwords]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14820</guid>

					<description><![CDATA[The Keychain is a system-wide feature on macOS that securely stores account passwords for applications. Until Xojo 2025r1, updating the password for an existing KeychainItem—that&#8230;]]></description>
										<content:encoded><![CDATA[
<p>The Keychain is a system-wide feature on macOS that securely stores account passwords for applications. Until Xojo 2025r1, updating the password for an existing KeychainItem—that is, for a given Service Name—required first removing the item from the Keychain and then recreating it from scratch. Not exactly the most efficient process. But with the introduction of the KeychainItem.UpdatePassword method in 2025r1, things have gotten much easier. Read on to see how you can take advantage of this new functionality.</p>



<span id="more-14820"></span>



<p>Starting with 2025r1, there’s no longer any need to delete an existing Keychain item just to update its password. All you need is a <a href="https://documentation.xojo.com/api/macos/keychainitem.html#keychainitem">KeychainItem</a> instance with a non-zero Handle, in other words, a properly initialized item. And the best way to get a reference to an existing KeychainItem is by using the System.Keychain.FindPassword method. For example, the following code snippet from a method with the signature FindPassword(serviceName As String) As KeychainItem:</p>



<pre class="wp-block-code"><code>Var itemToFind As New KeychainItem
Var password As String

// Name to find
ItemToFind.ServiceName = serviceName

// Get the password
password = System.Keychain.FindPassword(itemToFind)

Return itemToFind

Catch e As KeychainException
  Return Nil</code></pre>



<p>This retrieves the password for a given Keychain item stored under the Service Name passed as the serviceName parameter. If the call to System.Keychain.FindPassword raises a KeychainException, it means there&#8217;s no password stored in the Keychain for that Service Name so we return Nil. But if the method successfully retrieves a password, it means we have a valid, properly initialized KeychainItem we can use to call UpdatePassword.</p>



<p>For example, create a new method with the following signature:</p>



<pre class="wp-block-code"><code>Public Sub CreatePassword(pass As String, label As string, serviceName As String)
  // Let's see if we have a password for the item already.
  // If that is the case, we need to update it instead of
  // creating it!
  
  Var itemToFind As KeychainItem = FindPassword(serviceName)
  
  // If we don't get a Nil KeychainItem, that means that we should
  // update the password for such KeychainItem, instead of creating a new one!
  
  If itemToFind &lt;> Nil Then
     itemToFind.UpdatePassword(pass)
  Else
    // We got a Nil KeychainItem… what means that there is not
    // such item in the user Keychain yet, so let's create it.
    
    itemToFind = New KeychainItem
    itemToFind.Label = label
    itemToFind.ServiceName = serviceName
    System.Keychain.AddPassword(itemToFind, pass)
  End If
  
  Catch e As KeychainException
    MessageBox("Keychain error: " + e.Message)
    
End Sub</code></pre>



<p>As you can see, this method takes three string parameters: the password you want to set or update, the label to use for the Keychain item (particularly useful when adding a new password for a given Service Name) and the Service Name itself, which is associated with the password.</p>



<p>The first thing this method does is call the FindPassword method we saw earlier. If it returns a non-nil object, we simply update the password. However, if the FindPassword method returns a nil object, we create a new KeychainItem from scratch using the provided label and serviceName parameters, then add the new password to the user&#8217;s Keychain.</p>



<p><a href="https://drive.google.com/file/d/18CvvlDvNi0mFRqCscrxmfklpZo3lYKY3/view?usp=share_link">Download this example project</a> to experiment adding, deleting and/or updating passwords to your macOS Keychain.</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 2 &#8211; Password Generator</title>
		<link>https://blog.xojo.com/2018/06/29/just-code-challenge-week2/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 29 Jun 2018 01:00:53 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[Challenge]]></category>
		<category><![CDATA[Passwords]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4364</guid>

					<description><![CDATA[#JustCode Challenge Week 2! This week I took inspiration from a feature in 1Password that can generate a password suggestion. This desktop app allows you to specify a desired password length and the number of digits and symbols to include in it.]]></description>
										<content:encoded><![CDATA[<p>In week 2 of the <a href="https://blog.xojo.com/2018/06/18/jump-right-in-just-code-challenge/">Just Code challenge</a> I took inspiration from a feature in <a href="https://1password.com">1Password</a> that can generate a password suggestion. This desktop app allows you to specify a desired password length and the number of digits and symbols to include in it.</p>
<p><span id="more-4364"></span></p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4367 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/06/2018-06-06_12-25-22.png" alt="" width="366" height="259" /></p>
<p>Here is the Window layout in the Xojo IDE:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4369" src="https://blog.xojo.com/wp-content/uploads/2018/06/2018-06-06_11-53-55.png" alt="" width="1159" height="694" /></p>
<p>I&#8217;m using a read-only <a href="http://developer.xojo.com/textfield">TextField</a> to display the generated password. There are a couple <a href="http://developer.xojo.com/pushbutton">PushButtons</a> for copying the password text to the clipboard and for generating a new password. I use Slider controls to set the length of the password and the number of digits and symbols to include, along with corresponding labels.</p>
<p>When the window opens, it populates some arrays with the acceptable characters that can be used for letters, digits and symbols. In particular, some characters are excluded such as &#8220;O&#8221;, &#8220;o&#8221;, &#8220;0&#8221; and quotes because those are difficult to distinguish. The code to do this is in the Open event:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4370" src="https://blog.xojo.com/wp-content/uploads/2018/06/2018-06-06_13-29-50.png" alt="" width="853" height="785" /></p>
<p>The last line calls the GeneratePassword method which uses the settings from the user interface to generate a password. This way you&#8217;ll have a password displayed immediately when the window appears.</p>
<p>The GeneratePassword method first determines how many digits are needed, making sure it does not exceed the requested password length. Then it adds any symbols, also ensuring it does not exceed the set length. Lastly, if more characters are needed it adds letters to reach the desired length.</p>
<p>The characters are added to a String array that is then shuffled to mix all the parts together. Try commenting the Shuffle line out and when you run the project you&#8217;ll see that numbers always appear first, followed by symbols and then the letters. Here is the GeneratePassword code:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-4371" src="https://blog.xojo.com/wp-content/uploads/2018/06/2018-06-06_13-30-49.png" alt="" width="853" height="785" /></p>
<p>A similar technique is used by the RandomDigit, RandomLetter and RandomSymbol. It uses the Shuffle method to randomize the appropriate array and then returns the first item.</p>
<p><a href="http://files.xojo.com/JustCode/PasswordGenerator.zip">Download the Password Generator project file</a>.</p>
<p>Download and check out earlier projects:</p>
<p>Week 1: <a href="https://blog.xojo.com/2018/06/22/just-code-challenge-week1/">Color Picker Desktop App</a></p>
<p>Discuss your Week 2 project in the Xojo forum:</p>
<p><a href="https://forum.xojo.com/48550-just-code-challenge-week-2-projects">Just Code Challenge Week 2 Projects</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Ultimate Password Solution</title>
		<link>https://blog.xojo.com/2017/05/04/the-ultimate-password-solution/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Thu, 04 May 2017 12:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Passwords]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/08/18/the-ultimate-password-solution/</guid>

					<description><![CDATA[What if websites required that users use the secure passwords it generated for you? Removing the user's ability to choose their own password may seem draconian, but it would be the ultimate password solution.]]></description>
										<content:encoded><![CDATA[<p><a href="https://passwordday.org">World Password Day</a> brings attention to some simple steps everyone can take to secure their digital life: 1. Create Strong Passwords, 2. Use a different password for each account, and 3. Get a password manager, no, not a post-it note in your desk drawer!</p>
<p>The best password is one that is diffcult to guess. But difficult to guess takes on a new meaning when hackers use computers to do the guessing. Hence, the best password becomes one that would take a computer so long to guess that it&#8217;s not practical to do so. That means a long series of random characters and the longer and more random, the better, and a different password for every site you use.</p>
<p><span id="more-250"></span></p>
<h3><strong>Make Your Passwords Strong and Long</strong></h3>
<p>If every password you created was different set of 100 randomly-selected characters, breaking into an account would be close to impossible for a hacker. The lower-half of the ASCII character set (the most commonly used characters) is 128 characters. The number of possible passwords for a 100 character password made from randomly-selected, lower-ASCII characters would be 100 to the 128th power. That number is so large that it would take the typical PC years to find a match. But again, the problem is that users can&#8217;t even remember a handful of <em>meaningful</em> passwords just 10 characters long. If the average person has 50 things in their life that each need a password, how do we get them to remember 50 unique, <em>random</em> 100 character passwords? We don&#8217;t.</p>
<p>Password manager software such as the Keychain on OS X, <a title="1Password" href="http://www.1Password.com" target="_blank" rel="noopener noreferrer">1Password</a>, or <a title="Roboform" href="http://www.roboform.com" target="_blank" rel="noopener noreferrer">Roboform</a> that can generate these types of passwords and store them securely on the user&#8217;s device. The long, unique and random passwords can then be entered automatically so the user doesn&#8217;t have to remember them or deal with them. How do we get people to use a password database? Easy &#8211;</p>
<h3>We don&#8217;t allow people to choose their passwords.</h3>
<p><img loading="lazy" decoding="async" class="size-medium aligncenter" src="https://media.giphy.com/media/cnQn0eeU9dmZW/giphy.gif" width="450" height="252" /></p>
<p>Stick with me here. Imagine if websites and applications that required passwords generated the them for you rather than allowing you to choose one? Hello Mr. Perlman, your password is:</p>
<p>KÂs-&amp;DÂbu^ÂF|ÂUÂÂ]qÂÂÂÂ95ÂÂÂIkKXjoÂ;O6ÂuÂÂRUÂdÂ!AUÂx(IÂwÂÂ~ÂYlÂF Â#ÂÂÂÂ:8?LD$Â5tfK%P.VbT9HQi%Y[Â7a</p>
<p>You would have no choice but to use a password database to keep track of them. Now this might seem a bit extreme. However, requiring a password at all seemed extreme when we first started on the web. <strong>If websites and software applications generated the passwords at random, people would have no choice but to use a password database. It&#8217;s the login equivilent of a seatbelt law.</strong></p>
<p>In this scenario, programs written by hackers to guess passwords become obsolete. Now you might say that the hackers will just turn their attention to hacking your password database. That&#8217;s true but that&#8217;s a much bigger problem for the hacker. They don&#8217;t want <em>your</em> credit card number. They want <em>thousands</em> of credit card numbers. Getting them one at a time, person by person, is totally impractical.</p>
<p>We&#8217;ve blogged<a href="http://blog.xojo.com/2015/10/09/tips-dealing-with-the-problem-of-passwords/"> about web security and passwords before</a>. Well-designed websites don&#8217;t store your password, they store a <a href="https://en.wikipedia.org/wiki/Cryptographic_hash_function">hash</a> of your password. When you attempt to login, they hash the password you type and compare it to the hash of the password in their database. If the two match, the site knows only that that they matched. The website still does not know your password, even if that website generated your password, because it shouldn&#8217;t be storing it. That&#8217;s what we do with user accounts at Xojo.</p>
<h3><strong>What would be required to implement such a thing?</strong></h3>
<p>First, websites and applications need to allow longer passwords. Passwords are usually stored in a database field so changing the field to allow a 100 character password is two seconds work. Next, you need to write the code to generate the random passwords. In Xojo, that code is a trival 5 lines. Ideally, the code creating the password could pass the password back to the user&#8217;s device securely so that it could be automatically stored in their password database without the user having to be involved.</p>
<p><strong>Removing the user&#8217;s ability to choose their own password may seem draconian, but it would be the ultimate password solution.</strong> Existing password databases can be made to interact seemlessly with websites to store new passwords and pass them back when needed. Of course, websites need to be properly written to be secure and hosted in secure facilities. But the great thing about this solutions is that instead of hackers having to target 100,000 servers with valuable data on them, they have to attack potentially hundreds of millions of devices which is totally impractical.</p>
<p>And exactly how long would it take for a PC to crack that 100 character password I suggested above?</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-2639" src="https://blog.xojo.com/wp-content/uploads/2015/08/WPD16-GIF-Passwords102-1.gif" alt="" width="734" height="362" /></p>
<p>According to <a href="https://howsecureismypassword.net">HowSecureIsMyPassword.net</a>, it would take 69,003 NONAGINTILLION years to crack your password. I&#8217;m quite certain it&#8217;s long enough.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>There&#8217;s No Excuse For Storing Passwords</title>
		<link>https://blog.xojo.com/2017/05/04/theres-no-excuse-for-stolen-passwords/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Thu, 04 May 2017 06:00:00 +0000</pubDate>
				<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Passwords]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2014/08/06/theres-no-excuse-for-stolen-passwords/</guid>

					<description><![CDATA[There's really no excuse for a website to store your password - ever. If a website uses a good hashing algorithm, it's completely impractical to decrypt the hash back to the original password. ]]></description>
										<content:encoded><![CDATA[<p>A few years ago it was <a title="CNN: 1.2 billion stolen passwords" href="http://money.cnn.com/2014/08/05/technology/security/russian-hackers-theft/index.html?hpt=hp_t1" target="_blank" rel="noopener noreferrer">reported</a> that Russian hackers had stolen 1.2 billion usernames and passwords from a variety of websites. This was only possible because those websites were storing the actual password. Because it&#8217;s <a href="https://passwordday.org">World Password Day</a> and because this is web security 101, let&#8217;s discuss why there&#8217;s really no excuse for a website to store your password &#8211; ever.</p>
<p><span id="more-252"></span></p>
<p>A website that has a login only needs to store a <a title="Cryptographic Hash Function" href="http://en.wikipedia.org/wiki/Cryptographic_hash_function" target="_blank" rel="noopener noreferrer">hash</a> of your password after you create your account (or change your password). There is never a need to store the password itself. Hashing is one-way encryption. <strong>If a website uses a good hashing algorithm, it&#8217;s completely impractical to decrypt the hash back to the original password.</strong> When you go to login to a website, the site will take the password you just entered, hash it and compare that hash to the hash created when you created your login (or last changed your password). If they match, it knows the passwords that were used to create both hashes are the same but it still doesn&#8217;t ever need to know the password itself.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-2621" src="https://blog.xojo.com/wp-content/uploads/2014/08/password.png" alt="" width="500" height="326" /></p>
<p>We&#8217;ve <a href="http://blog.xojo.com/2015/10/09/tips-dealing-with-the-problem-of-passwords/">blogged before</a> about how to securely handle passwords in app development. There are simple techniques that make it easy to disassociate the password hash from the user. That way if a hacker got your database, got all the hashes and was willing to put the <em>enormous</em> computing resources into decrypting a specific hash for a specific user, it still would not matter because they wouldn&#8217;t know which hash belonged to which user.</p>
<p>Anyone responsible for the security of a website should know all this. <strong>This is web security 101.</strong> While the identities of these websites were not made public, you can bet they were sites with a lot of users. It&#8217;s hard to believe that sites with large numbers of users wouldn&#8217;t be doing these security basics.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tips: Dealing with the Problem of Passwords</title>
		<link>https://blog.xojo.com/2015/10/09/tips-dealing-with-the-problem-of-passwords/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 09 Oct 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Passwords]]></category>
		<category><![CDATA[Tips]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/10/09/tips-dealing-with-the-problem-of-passwords/</guid>

					<description><![CDATA[Tips on how to better handle user passwords in your apps. Though too much security is never enough, as developers, there are things we can do to keep our users' passwords secure.]]></description>
										<content:encoded><![CDATA[<p>Passwords are a problem, as we frequently see in the news when databases containing password and login information are hacked and exposed.</p>
<p>Though <a href="/2014/06/19/too_much_security_is_never_enough/" target="_blank" rel="noopener noreferrer">too much security is never enough</a>, as developers, there are things we can do to keep our users&#8217; passwords secure.</p>
<p><span id="more-266"></span></p>
<p>The best way to not allow passwords to be compromised is to not store the password at all. Unfortunately, I&#8217;ve seen far too many apps that have databases with a &#8220;password&#8221; column that contains the actual password! And I&#8217;m sure you&#8217;ve seen web sites that, when you click the &#8220;forgot password&#8221; link, send you an email with your actual password! This is not good. <strong>The only one who should know the password is the person who created the password.</strong></p>
<p><img decoding="async" style="width: 320px; display: block; margin-left: auto; margin-right: auto;" title="security keys" src="https://blog.xojo.com/wp-content/uploads/2015/10/keys-525732_1280.jpgt1466486449161" alt="security keys" data-constrained="true" /></p>
<p>So the first thing to do is to <em>not</em> store the password. Instead store a one-way hash of a password. A hash is a function that given a value, returns a new value of a fixed length that is always the same for the original value. A one-way hash is a hash that can convert text to a hash value but cannot convert the hash value back to the original text.</p>
<p>It just so happens that Xojo has several built-in one-way hash functions in the <a href="http://developer.xojo.com/xojo-crypto">Crypto</a> namespace: MD5, SHA1, SHA256, SHA512 and PBKDF2.</p>
<p>For example, given a password &#8220;frenchfries&#8221;, MD5 generates this hash value (converted to hex):</p>
<p>8D32A4B407DE20D2465467EE38DEF24C</p>
<p><strong>The idea is that instead of storing the actual password, you use the hash of the password.</strong> To validate that the password is correct, when the user logs in you calculate the hash of the password they entered and then check to see if it matches the hash of the password you have stored. If they are the same then you know the password is correct even though you do not know the actual password.</p>
<p>This strategy is a great start, but it has a flaw: it is susceptible to a &#8220;brute-force&#8221; attack. This is where a nefarious hacker pre-calculates hash values for large amounts of common words. This is referred to as a <a href="https://en.wikipedia.org/wiki/Rainbow_table">rainbow table</a>. Since most people choose relatively simple passwords, they will more than likely be found in a rainbow table. If a hacker gets access to your hash value and they know how it was calculated, they can then look it up in the rainbow table to see what the plain text password is.</p>
<p>One way to help mitigate this is to use a &#8220;salt&#8221; along with the password to create the hash. The salt is an extra value that you add to the password to generate hashes that make rainbow tables largely useless. You can use the same salt value for all the passwords or you can use something more specific for each password.</p>
<p>Creating an MD5 hash on the combination of the hash for &#8220;frenchfries&#8221; and the text &#8220;salted&#8221; generates this hash using MD5:</p>
<p class="p1">AE4D2A78B0681171F8E030C30A20F8F8</p>
<p>Such a value is not likely to show up in a rainbow table anywhere because it&#8217;s specific to you, thus limiting its general usefulness. A hacker would actually need to figure out how you are creating your salt value before they can generate a rainbow table.</p>
<p>Using a hash with a salt works well, but you also have to use a secure hashing function. It has <a href="http://arstechnica.com/security/2015/10/sha1-crypto-algorithm-securing-internet-could-break-by-years-end/">been known for some time that MD5 and SHA1 are no longer secure hashing function</a>s and are not recommended for use. The primary problem is that it is possible for two completely different values to generate the same hash. This flaw has been used to fake security certificates among other things. You may think it does not matter much for your purposes, but don&#8217;t be the one that is easier to hack. Use one of the other available hashing functions such as SHA256.</p>
<p>But even better, you can use the <a href="https://en.wikipedia.org/wiki/PBKDF2">PBKDF2</a> function which is essentially a &#8220;slow&#8221; function which makes brute-force attacks more difficult to achieve. PBKDF2 with a salt and SHA256 can work really well. Here is an example:</p>
<pre>Dim salt As Text = "salted"
Dim saltData As Xojo.Core.MemoryBlock
saltData = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(salt)
Dim password As Text = "frenchfries"
Dim passwordData As Xojo.Core.MemoryBlock
passwordData = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(password)
Dim hashData As Xojo.Core.MemoryBlock
hashData = Xojo.Crypto.PBKDF2(saltData, passwordData, 500, _
  32, Xojo.Crypto.HashAlgorithms.SHA256)</pre>
<p>The resulting hash is a <a href="http://developer.xojo.com/xojo-core-memoryblock">MemoryBlock</a> so to display it, you&#8217;ll want to convert it to a hexadecimal value. This code can easily do that:</p>
<pre>Private Function ConvertToHex(mb As Xojo.Core.MemoryBlock) As Text
  Dim hex As Text

  For b As Int8 = 0 To mb.Size - 1
    hex = hex + mb.UInt8Value(b).ToHex(2)
  Next

  Return hex
End Function</pre>
<p>The hash for &#8220;frenchfries&#8221; with the salt &#8220;salted&#8221; yields this hash value using the above PBKDF2 function:</p>
<p class="p1">6A9C1E745EEBD7A9687DF04FC61E5C4C685537EEB4A3384531DE5687270C9DF4</p>
<p><a href="http://files.xojo.com/BlogExamples/PasswordHashing.xojo_binary_project">Download the sample project</a> to play around with the various hashing functions.<br />
<span><span style="font-size: xx-small;"><i>Updated (Sep 11, 2018) to ensure correct hex values are always displayed.<br />
</i></span></span><em><span style="font-size: 10px;">Updated (Oct 15, 2015) to ensure 2-digit hex values are used.</span></em></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
