In today's tutorial, I'll be walking you through the essential skill of securely storing your users' OpenAI keys. This comprehensive guide is tailored for developers at all levels who want to ensure the highest security standards in their applications. We'll start by examining 3 common but insecure methods of key storage, discussing the vulnerabilities each method presents. Then, we dive into the best practices for secure storage, followed by a hands-on coding session where we implement the most secure solution.
Timestamps: 00:00 Introduction 00:34 3 Common Vulnerabilities With Storing User Keys 00:57 Vulnerable Scenario 1: Database Only 01:55 Vulnerable Scenario 2: Front End Only 03:01 Vulnerable Scenario 3: FE + BE 04:37 Step-by-Step Solution 07:10 Free Source Code 07:40 Application Overview 08:58 Step 1: Accept User OpenAI Secret Keys 10:24 Step 2: Randomly Generate Encryption Keys 13:42 Step 3: Encrypt OpenAI Key 18:06 Step 4 & 5: Save & Encrypted Keys to Client and Database 24:21 Step 6: Decrypt Encrypted OpenAI Key 29:22 Final Application Demo 31:00 Outro
Hey guys, in this video, you're going to become an expert at protecting your user's private
keys, which means we're going to be covering three potential security issues that you might
have in your code right now.
From there, we'll quickly cover the solutions and to help connect all the dots, I actually
went ahead and built this app for you guys so that you guys can see these security best
practices in action.
And to help make your life easier, I'm giving away all the source code completely for free
so that you guys can just start copying and pasting these solutions into your own projects.
So enough chit chat, let's go ahead and dive in and start securing your apps right now.
So to help us better understand the three common vulnerabilities that might be happening
in your code right now, let's pretend that you just built an app that generates funny
dad jokes by connecting to open AI.
All we need is for our users to give us their open AI keys and then we handle the rest.
So now that you have some background, let's go ahead and break apart this app into its
core components and uncover just how vulnerable it really is.
For scenario one, we're going to pretend that we're saving our user's super secret open
AI keys to our back-end database.
Well, here are the two problems with this approach.
First, you and I could accidentally make a mistake.
For example, we could forget to add our .env file to our gitignore list, which would mean
we've accidentally leaked all of our environment variables out to the internet through our
GitHub account.
So anyone who has access to GitHub could go in there, swipe our environment variables,
and just grab all the data from our database.
And because everything's in plain text, they could just swipe it.
Now that's with you and I making a mistake.
The second thing is the database provider themselves could have a leak.
And in that case, once again, anyone who is malicious could go through the database and
actually swipe all of our users open AI keys and do whatever they would want with them
because they're in plain text.
So anyone could grab them.
So saving the keys in our back-end database in plain text is a no-go.
So let's move on to scenario two.
So for scenario two, we're moving away from the back-end database because that's scary
now.
And we're just going to save our user's super secret open AI keys to the local storage in
our front end.
This should be safe, right?
Because everything's just on the client and nothing should be able to access these super
secret keys.
Well, that's not entirely true.
Here are two scenarios where this could actually come to bite you.
First, if the user has a rogue Chrome extension installed or it gets compromised, that Chrome
extension can actually scrape all of your different local storage keys and actually
find your users open AI keys.
I know I said key a bunch, but once the Chrome extension has access to these secret information,
they could go off and start charging your client and rack up a huge bill for them.
The other scenario is if the user goes to some sort of site that they're not supposed
to and gets a small virus, once again, that virus or malicious code could scrape the local
storage and actually grab your open AI keys that you're saving on your user's behalf.
So once again, the front end saving your plain text keys in local storage is also not safe.
So let's go ahead and talk about scenario number three.
So now that we're in scenario three, we're starting to learn that the front end local
storage isn't the problem and the back-end database isn't the problem.
The root problem is the fact that we're saving our users open AI keys in plain text.
So now we decide to get smarter and start storing our users open AI keys after we've
encrypted them.
So to do this, what we do is we make a new encryption key that we save in our front end
code and let's just say it's encryption keys equal to one, two, three.
Well now we encrypt every open AI key as it comes in.
Once it's encrypted, we save it off to our back-end database.
Now, whenever something goes wrong in the future, and let's say there's an accidental
leak in our database, well, the malicious users will not be able to access our users
open AI keys because all they're getting is encrypted mumbo jumbo on the back end.
But we're still not out of the clear.
And the reason why is because these malicious users still have access to our encryption
key.
And the reason why is because we have decided to encrypt our users open AI keys on the front
end, which means the encryption key itself is exposed.
So anyone who parses through our front end code can grab that encryption key and they're
able to decrypt all the information inside of our database.
So once again, we're back at the same problem where bad people have our users open AI keys
and can start racking up a bill.
So now that we've covered how everything can go wrong, let's go ahead and move on to the
solution, which is the most safe and most practical way to start saving and encrypting
your users open AI keys.
So now that we've covered the three different scenarios and gone through all the problems
with them, what we're going to do is cover the solution now and walk you guys through
how this works in six simple steps.
And then we're going to talk about how this is the most safe option.
So for step number one for our solution, what we're going to do is accept our users inputs.
So we're going to be able to access their open AI keys.
And then it's up to us to start encrypting them.
But this time, what we're going to do for step two is we're randomly going to generate
our encryption keys on the front end.
We're not going to hard code them.
We're going to randomly generate them from there.
And step number three, we're going to encrypt our users open AI keys.
And what we're going to do with these encrypted open AI keys is first.
And step number four is we are going to save the encrypted keys to local storage so we
can access them later.
In step five, we're going to save those randomly generated encryption keys off to our
backend. From there, whenever we want to decrypt the users open AI keys and make a
request to open AI, all we have to do is just fetch our encryption keys from our
backend database, pass in our encrypted open AI keys on the front end, and then just
send a request through HTTPS over to our backend to make a call over to open AI.
And this is going to be secure because we're using HTTPS to send over our decrypted
open AI key. So everything's going to be secure from end to end.
So that's how it works in six simple steps.
And we're obviously going to, in a few minutes, code the solution up so that you guys
can see these steps in action.
And outside of that, I just want to cover why this option is so much more safe than
everything else that we've done.
Well, in this option, what we're doing is if the user downloads a rogue Chrome plugin
for whatever reason, and that Chrome plugin scrapes all the different local storage
variables and gets access to the open AI key, well, it actually doesn't matter because
that open AI key is going to be encrypted.
So check on the front end.
Well, let's look at the backend.
If for whatever reason, we accidentally save our environment variables to a public
folder or if some malicious user gets access to our database, once again, all they're
going to have access to is going to be the randomly generated encryption keys.
And they can't do anything with that.
The only way someone can get access and really mess with our users open AI keys is if
they, A, are able to hack or maliciously take advantage and exploit the user's front
end to where they can scrape the local storage key.
And then second, they also need to be able to steal data from our database.
So we're protecting our data in two different places, which means we do not have a
single point of failure.
So this this solution is infinitely more secure than what we've been doing previously.
And enough talking about the solution.
Let's actually hop over to the code now and start coding this up.
Oh, wait, real quick.
I just want to mention two things.
First, to grab the source code for this project, all you have to do is just scroll down
in the description and there'll be a link to where you can grab the source code for
this video and all of my other full stack AI projects.
And it would mean the world to me while you're scrolling down.
If you could hit that like and subscribe button.
Second, if you need any help with this project, for whatever reason, feel free to drop
a comment down below, or you can actually click the link in the description, which will
help you book a one-on-one call with me where we can go over whatever problems you're
having and we'll try and get to the bottom of it.
But enough of that, let's get back to the video.
So now we're diving into the fun stuff where we're actually going to start coding up
and implementing these six steps that we just talked about a second ago to start
securing your users open AI keys.
And before we do that, I do want to mention just as a high level overview, the
application that we're about to run through.
At a high level, this is a Next.js application that we're going to be using TypeScript
for. And this Next.js application does have some backend logic, which we'll touch on
in just a second. But outside of that, it is connected up to a database like you saw on
our example diagram beforehand.
And we'll also have this application hooked up to authentication.
We're using Clerk. And the reason why is because as we generate those random
encryption keys, we need to know which user those encryption keys belong to.
So we're going to have to tie those together in our backend database.
Now, if any of this seems overwhelming or you want some more guidance on this, once
again, feel free to grab the source code and the link below.
But also, you definitely are going to want to check out two of my previous videos that
I've done where I create an entire full stack application from scratch so that you
guys can actually build something like this yourselves completely from scratch.
One of those is going to be an AI fitness coach and the other one is going to be an
AI lead magnet. Both great videos.
I recommend you definitely check out after this.
All right. Enough talking. Let's go ahead and dive into step number one, where we're
going to start asking and accepting our users open AI keys.
So like I just mentioned, the first thing that we're going to work on is accepting our
users open AI keys that they need to type into right here.
And what you'll notice is I've actually went ahead and cleared out our database and
all of our local storage so that we're working from scratch and we're going to work
our way all the way up to generating our AI generated dad jokes.
But the first thing that we're focusing on right now is accepting our users inputs
right here. So here's how we do that in our next year's application.
Well, the first thing is we need somewhere inside of our application to store the
state of this input field.
Well, how do we do that? We do it right here.
We create a new use state where we're going to store an open AI key
and this open AI key is going to be a string.
Well, how do we update it? Well, if you actually scroll down to later in the file,
you'll see that we've set up our HTML code so that we have this right
here where you can see we have our open AI key.
We have a label to the left and now we have our input.
The purpose of this input is to be an input of type password so that as the user
types, you know, it shows up as the dots.
So we're not just revealing it to the world.
And the other thing is as the user types in their password or open AI key,
we are actually updating it in real time using this set open AI key function in
real time. So that's how we're going to do step one.
Now let's actually move on to step two,
where we're going to be randomly generating our encryption keys. Well,
to do this,
what we need to do is scroll back up to the top of our code and we need to talk
about two things first at a very high level.
So the first thing you realize when it comes to an encryption key is we actually
don't have an encryption key over here on the right side of our application.
We actually have a passphrase and a salt. Now, what the heck are these? Well,
this leads us to point number two.
We are actually using a combination of a passphrase and a salt to generate our
encryption key.
And the best way to demonstrate this is to actually go over to our generate
passphrase and generate salt functions in our cryptos utils file that we also
have inside of this project.
So let me walk you through the passphrase and then I'll walk you through the
salt and explain what they're doing.
And hopefully this will help you tie together and prepare you for step number
three,
where we're actually going to encrypt the open AI key that we just typed in.
So the first thing is, is we need a passphrase.
This is basically going to be the encryption key. However,
what we're going to do is actually just randomly generate it.
But there is an option.
And this is why I wanted to show this to you guys with salt is we could have
allowed our user to actually type in a passphrase here.
They could have typed in super secret password, but just for application,
we're just trying to make this as seamless as possible.
So we're auto generating a passphrase for them. However,
if we had allowed our users to type in a passphrase,
what you want to do is add salt to it. Now,
this might be a funny term if you've never heard it before,
but basically what salt does is it helps people who commonly use the same
passwords. Like, let's just say an example,
password that someone might use is just like, you know, someone's older.
They might just do like, yep, that's my password. Well,
that's very bad practice.
And what you want to do is actually just add some salt to the end of it.
And salt is basically just random keys that get added to the end of a
passphrase to help make it basically extra unique. And I think this is,
like I said, this is probably one of the best examples I've seen out there.
That best definition that explains it,
it's just making the password hash output unique. So for example,
if we were to, you know, hash 1, 2, 3, 4, 5, 6, 7, 8,
with common hashing functions, you would always get the same output.
And it would be very easy for a experienced hacker or someone else to basically
reverse engineer like, Oh yeah, that's this password.
But by adding some extra random keys at the end of this password that are going
to be 16 characters long,
that hash is going to be very unique and that's going to prevent hackers from
being able to reverse and basically look up very common passwords.
So what we're going to do is we're going to generate the passphrase and generate
the salt just to get you guys some more experience using common cryptography
practices. So that's what we're going to do.
We're going to call these two functions and generate passphrase and generate
salt whenever the user clicks, generates salt and passphrase.
And just to show you that that in here,
what we're going to do is if we scroll down,
you'll see that we have a function called generate random credentials.
And that's exactly what we're doing. We're generating a new passphrase,
16 characters long.
They were generating a new salt and what we're going to do is save the salt and
passphrase and update the state, which we're saving right here.
So I'm gonna go ahead and click it so you guys can see it update in real time.
So when I click it, fantastic,
we now have the passphrase and now have the salt inside of our application.
And you'll also notice whenever I clicked it,
it also enabled this encrypt button.
And that's just because the way I've set up the app is as we have continually
implement more and more of the key ingredients necessary to create an encrypted
key or decrypted key.
We're slowly going to give our app more functionality.
So let's go ahead and move on to step number three,
where we're actually going to start encrypting our open AI key using the new
encryption keys we just created.
So now that we're on step three,
where we're actually going to encrypt our open AI key,
I think the best way to go about this is to actually look at this from a high
level overview first, and then dive down deep into the actual implementation.
So I think the best way to do this is let's actually go down to the handle
encrypt function that gets triggered whenever we click this button and look at
the code.
Well,
the first thing you'll notice is we're going to call a encrypt key function.
Once again,
this is going to come from our utils package that we've defined and we'll dive
into this when we go into the detailed explanation.
But the important part is this is going to return an encrypted key or basically
the encrypted data that's going to then show up over here on our application on
the right.
So this is the encrypted data that we're also going to want to eventually save to
our local storage. So that's at a high level.
We're encrypting our open AI key.
Now let's actually dive in to this encrypt key function so that you guys can
actually see what's going on behind the scenes. Now, before we look,
I do want to mention that this is a little bit complicated. Don't worry.
You don't have to understand how it works.
You just need to know that you need to use it is the important part and feel
free to talk to ChachiBT to dive into a super detailed explanation of how this
all works if you want to go down the rabbit hole of encryption and
cryptography. So let's go ahead and dive in.
So what you'll see in our backend cryptos util library function is we're going
to take in three things. The first is going to be the key,
which is our open AI key. The next is the passphrase.
And then finally we're going to take in the salt.
So what we're going to do from here, we're going to go through this step by step.
And before we do this,
I do want to show you what's actually going on behind the scenes.
So what we're trying to do is take in our plain text, which is our open AI key.
Then we're going to take in our secret key or our open AI key.
Then we're going to pass in an initialization vector,
which we're going to talk about in a second.
Then we're going to pass all of that in and to this encryption algorithm,
and that's going to generate everything that we need to have our encrypted key.
So here's how this works. I'm going to keep this up because this is very important.
So the first thing we're going to do is we're not just going to encrypt our
plain text key.
We're going to do it 10,000 times or some arbitrary number of times,
because the more times it gets encrypted,
that's another layer of security to basically make sure that you end up with
something that's very unique. So that's not easily to reverse engineer from there.
What we're going to do is create the key size.
So this is basically what's going to get, this will make more sense in a second,
but this is the key, our encryption key size.
And then from there we're going to have our IV size and IV stands for
initialization vector. Basically all initialization vector does.
It's basically just an arbitrary number that can be used with a non-secret key
for encryption to foil cyber attacks. Basically the long story short,
the more randomness, the more iterations that you can do when encrypting keys,
the better we're just trying to protect our users here.
So I'm not going to walk through everything that's happening here,
but I will just mention that we're using the node forge library to a
use our passphrase, our salt,
and iterate everything 10,000 times to generate
everything that we need to have our encryption key and our initialization
vector. So that's all you need.
We just generating the initialization vector in our new secret key.
That's what we're doing right here. And then once we've done that,
what we're going to do once we've defined them,
what we're going to do next is use the AES. Basically,
this is our encryption algorithm on our derived key.
So that's going to be our encryption key to start our cipher.
And once we've done that,
what we're going to get out of this is going to be our encrypted key.
This is basically going to be the encrypted version of our open AI key.
That's going to come over here. So I know that's a lot.
Please feel free to dive through this.
I would definitely talk to chat to BT to dive deeper into exactly what's going on
here, but I don't want to turn this into a multi hour tutorial.
The important part here is we are mixing everything up here so far,
generating a new encryption key,
and we're going to start saving that in the next step.
So let's go ahead and start actually clicking these buttons and actually seeing
how everything works.
And I'm going to go ahead and expand this so we can see what's going to happen.
Cause eventually we're going to have a save option to store everything locally
and to our backend. So I'm going to encrypt.
What we expect next is to show off our new encrypted key.
So that looks great.
And now what we can do is go ahead and move on to step four,
where we're going to start saving everything that we've generated so far,
our passphrase and salt to the backend and then save off our encryption key to
our local storage. So let's go ahead and start working on that now.
So I went ahead and actually split the screens because now we're actually going
to be diving deep into the save functionality and they're just going to be a lot
of codes.
So I want to make sure everything's big so you guys can see exactly what's going
on. So let's talk about this. Whenever we save,
we want to save our salt and passphrase to our database.
And we want to save our encrypted key to local storage.
So let's actually see what happens when we head back over to our front end code,
how we actually do this.
So the first thing is we're going to go down to the handle save function,
and this gets triggered once again, whenever we click that save button,
this is the on click event handler. So let's walk through this.
The first thing we're doing is we are going to set saving state so that whenever
the user clicks the button, we can actually update the UI.
So this will turn from save to saving. And then whenever it's done,
it'll go back to save. So that's just some nice UI.
But what we're going to do from there is we are going to make a request to our
backend database or our backend endpoint,
which is going to be a API user encryption.
So we're going to hop over here in a second,
but the important part to realize is all we're doing is we are making a post
request.
So that's going to push our salt and passphrase off to this backend endpoint.
And then from there,
the goal is to obviously save this data over to our database.
So let's go ahead and hop over there right now.
So we're going to go to API and then we said user encryption.
So here's what's happening at this endpoint. And once again,
we're using next JS 14.
So we're going to be using the app router functionality where we actually will
just define the post request endpoint right here.
So what we're going to be doing is first off,
we're going to check to see if the user is authenticated.
Now this is going to happen because we're using clerk and I'm not going to dive
too deep into this,
but just know we're using clerk to authenticate our user.
So whenever an authenticated user makes a request to our backend,
we'll actually be able to see who's making it.
And if I actually click over here,
you can see that this user is a type user and we're actually able to like grab
information out of it, such as, so I can go ahead and use, I'll show you guys,
I can do user and I can see everything.
Like I can see some of their name, email address and everything,
but we're mostly worried about the ID or the unique ID for this user. Great.
So what we're doing from here is we're going to pull out some information from
our requests. More specifically,
we're going to pull out the salt and passphrase that was generated on the
front end. So this information right here,
and what we're going to do is first validate to make sure that we have the
proper information. If not, we're just going to say, Hey,
you gave me the wrong data. Try again. And then from there,
this is where we're actually going to start working with our database. Now,
I didn't mention this earlier, but we're using Prisma.
Prisma is an ORM object relationship mapper.
And this just makes it easy to connect to our database.
So obviously we have JSON on the front end and then we are using a SQL database
on the backend. So we have to map those two. And if you want to go even deeper,
what we're doing is using, it's called cockroach DB.
So that's what we're using to set everything up.
And I'll just go ahead and show you what's happening on the backend.
So you guys can see it for yourselves, but just know what we're doing is,
like I said,
we're using Prisma to map our front end and backend code over to our SQL
database. And that SQL database is just, like I said, a cockroach DB,
and if you want to go even deeper, that's just a, it's a Postgres database,
but enough about that. Feel free to dig through the code on your own time,
but just know it's going to save this data to the backend.
And I'll show you it's working in just a second.
Then I'll actually go ahead and show you that right now, actually.
So what we have is we have a local instance of our database running on this
port, localhost 5555.
So if we actually go over here and type that in,
I just want to show you whenever we pull this up,
that you'll notice whenever we look at our user encryption table,
that there's no data here and that's what we're about to change.
So what we're going to do is if we come back over here,
you'll notice that what we're trying to do first is check to see if, Hey,
does this user encryption table have any data where
the user ID field matches our current user's ID? If so,
what I want to do is check. And just because the way we've set up our code,
every user will only have one set of encryption keys. So we just assume, Hey,
if this is over a length of zero,
that means the user already has encryption keys and we just need to update
them. But on the off chance,
if this is the first time the user is saving their keys with us,
we need to create this data. So this is what we're going to do.
Because right now, as you just remember, our database table is empty.
So we're going to have zero records. And what we're going to do is just say,
Hey, Prisma DB,
we're going to use the user encryption table and we are going to create the
data.
And all we're going to return back to our front end is going to be a success.
Let the user know that, yep,
we just saved off all the keys that you just generated. Fantastic.
So now that we know what's happening on the backend and with our database,
let's come back to the front end.
And all we're going to do here is the two things that we initially set out to
do. First check, we already are saving stuff to our database,
and now we need to save stuff to local storage.
So all we're going to do here is if we get back a status code of 200,
meaning everything was a success,
we just want to use the local storage to set a basically a key
value where the key is going to be our opening eye key.
And the value is going to be our encrypted key that we talked about earlier.
So let's go ahead and start actually saving and using this function here so that
we can see everything happening in action.
So the first thing we're going to do,
I'm going to go ahead and open up local storage so you guys can see what's
happening in real time.
So the first thing is I'm going to go ahead and hit save.
And I would expect something to pop up here and I would expect a new entry to
pop up in this table. So let's go ahead and click save. So it's going to save.
We get a little icon saying everything works properly.
Now when I come over here, I can actually see our encrypted open AI key.
And then finally,
whenever I go back to our database and refresh it, I can also see that. Yep.
We now have a new user encryption row where I can see the user ID.
This is the person who signed in.
I can see that this is their passphrase and this is their salt. And if you look,
this is M I K and then zero W E. If I go back over to application. Yep.
That looks right. And that looks great too. Great.
So now that we know that we're saving everything,
what we can do next is actually go ahead and move on to step number five,
where we're going to, sorry, we actually merged step four and five, which was,
you know, encrypting the keys and saving them.
So what we're going to do now is actually move on to step number six,
where we're going to start decrypting this key so that we can eventually start
making a request over to open AI. So let's go ahead and move on to the next step.
So now we're on step number six and we're actually going to decrypt and undo
everything that we just did when it comes to creating an encrypted version of
our open AI key. So what I'd like to do is walk you through at a high level,
what happens when we hit this decrypt button.
And then after that we'll dive into a deep version of what's actually going on
behind the scenes when it comes to undoing everything we just did. Okay.
So let's hop back over to our code and start going through this.
So at a high level, whenever you click the decrypt button,
you were actually triggering the handle decrypt function.
And what this is going to do is it's going to call the decrypt key,
which is going to be using node forge to actually do all the decrypting
functionality. But as you can see,
the main thing that's happening is we need to pass in our encrypted key,
our passphrase and our salt. So like I said,
that's what's happening at a high level. And once that gets completed,
what we're doing is we're actually just setting that decrypted key to show up
right here. So what you would expect to have happen as,
and you'll see this in just a second,
whatever I type in here will eventually show up here as well in our decrypted
key. So that's the, that's the end goal. That's what we're shooting for.
So let's go ahead and dive into the low level functionality that's happened.
So when we go over to our crypto utils file and look at our decrypt key,
what you'll notice is a few things.
So when it comes to the first perimeter that we're passing in, it says combined,
but that's, that's weird. That's not what we, you know, said earlier. Well,
that's because it's two things. It's actually our encryption key.
And then it's also going to be the tag or really our IV,
our initialization vector that we had earlier.
It's actually just all getting concatenated into one long string.
The next thing that's happening is we're, like I said,
passing in our passphrase and salt because that's what we need to basically undo
everything that we did earlier when it came to making this right here.
So just to, just to recap our secret key, that's our encryption key,
our initialization vector. That's the other one.
These two got joined together to be our combined first parameter right here.
And then our passphrase and salt basically just helps us undo everything that we
did earlier to work backwards, to get back to our plain text, open AI key.
So enough of that, let's keep diving into what's happening next.
So the first thing we're going to do is basically decode using basics before to
get back our combined combined key.
Then we're going to pull out our encryption key and then our tag.
We're just, like I said, doing some substring manipulation.
So we'll get, once we have our encryption key and our tag,
what we're going to do next is start deriving the key and IV.
And we're going to do basically undo everything that we just did earlier.
So the first thing is we're going to be doing 10,000 iterations,
but backwards to start deciphering our encryption key. So like I said,
I'm not going to walk through too much of this part. Cause like I said,
we're just basically just setting up everything we did earlier,
except with the goal of working backwards to decipher instead of encrypt.
Once again,
you'll also notice that we're using the same AES encryption algorithm that we
were using earlier whenever we were doing the create cipher.
So what we're doing here is once we're deciphering, once again,
we need to pass on our initialization vector. And then from there,
we're going to pass in everything else that's needed to decrypt our encrypted
key. Uh,
that way we can actually pull out our final unencrypted version of our open AI
key. I know it's a lot. Once again,
please just check with chat to BT to walk you through this,
because this gets very complicated very quickly.
And so I wouldn't get hung up on how, how it all works.
I would just know this is how you go from encrypted to decrypted as a mouthful.
Let's get back to the application. So what we're going to do once we have this,
I'm going to go ahead and just click it. So you guys can see that it's working.
So let's go ahead and back over here and now I'm just going to click decrypt and
what I would expect. Let's actually make this, we'll do it again.
So I can say hello world. Fantastic.
And I'm actually just going to encrypt it, save it.
And now I'm going to decrypt it.
So you should see the word hello world down here in the decrypted key.
So I'm going to click it. Yep. Fantastic.
So that's exactly what I typed up here. Now it's coming out down here,
but what I'm going to do next is actually go ahead and paste in an actual open AI
key so that now that we have our decrypted key,
we can actually go off and start making requests to our AI generated
endpoint, where we're going to make dad jokes that work from open AI.
And once again, what's happening here, not going to dive into it too deep,
but what we're doing is actually making a request to our endpoint.
Let me just show you right here. What we're doing is just using the,
we're using the open AI library and all we're doing, like I said,
this is an open AI tutorial,
but just know what we're doing is making a request with open AI.
We're passing in our unencrypted key.
And then from there, well,
you'll notice it's we're having to set the dangerously allow browser true.
And that's because they normally don't want you passing your user's keys around
because obviously as you just saw at the beginning of the video,
when we're going through working with the front end solution only that you're
going to run into a lot of security issues if you're storing your user's keys
unencrypted locally.
So it's up to us to be very protective about this.
And what we're going to do is basically just go off and use some prompt
engineering to make a dad joke and return it to the front end.
So we're going to do, I'm going to come back over here to our front end code.
I'm going to paste in a real key and then we're actually going to see it all
working in action. So now that we're going to generate our AI dad jokes,
I actually wanted to show you this working with a real open AI key.
So what we're going to do is head over to open AI and look at our keys and we're
actually going to make a new one. So we're just going to call this dad jokes.
This is just going to be, we're going to go ahead and create our secret key.
Obviously I'm going to delete this after I make this video,
but I just want to show you that this works. So we're going to copy it,
come back over to our application.
I'm going to delete everything and paste in our new open AI key.
Just go through the process one more time so you guys can see it all working.
So I'm going to generate new salt. I'm going to encrypt it.
That's going to come up with a super long encryption key.
Now we're going to save it. It's going to get saved to our backend database.
Now if I decrypt it,
what you'll notice is it's going to be our encryption key that just came from
back over here. So you can see this is literally it,
but now over here cause it got decrypted and what we can do now is actually go
ahead and generate our jokes and this will send off our basically decrypted key
off to open AI,
trigger the prompt that we just saw where it makes a silly dad joke and actually
just shows it. So let's go ahead and generate it, see what happens.
So it generates takes a few seconds and then now you can see that we're
generating our, our open AI dad joke.
So why don't scientists trust Adams because they make up everything and we can
actually keep triggering it. So it keeps working.
Why couldn't the bicycle stand up by itself? Because it was too tired.
So got it. Got to love some dad jokes, but yeah,
that's everything working in a nutshell.
We just ran through the six tasks that you need to go through in order to
protect your user's keys and actually make use of those keys when it comes to
working with open AI.
So that's a wrap for this quick demo of how this works. And once again,
please go check out the code so that you can download it and start implementing
these steps in your own application. But that's a wrap for this video guys.
I hope you're an expert now at protecting your user's private keys.
And don't forget real fast that you can just scroll down in the description to
grab the source code for the app that we covered in this project.
And you can also book a call with me at one-on-one so we can cover whatever
issues you may have you having. And finally,
I do want to mention that if you enjoyed this video,
you're definitely going to enjoy some of the other AI related content I have on
this channel. We cover full stack tutorials,
deep dives into different technologies.
So you're definitely going to check out one of the videos that YouTube is
recommending somewhere around here. That's right for this video guys.
And I look forward to seeing you on the next one. See ya.