Advanced Htpasswd/Htdigest file creator

Note: The strongest setting: Digest, then sha1, md5, and crypt. All are about the same over HTTPS (super-secure!!!)

Encryption Algorithm
Authentication Scheme

.htpasswd is a flat-file used by Apache and other applications to store usernames and password for HTTP authentication. Apache .htpasswd files may contain multiple types of passwords; some may have MD5-encrypted passwords while others in the same file may have passwords encrypted with crypt(3) and/or SHA-1. Usernames are limited to 255 bytes and may not include the character :.

Htpasswd Formats

Apache Servers recognize 4 formats for representing a password hash in the text file usually named .htpasswd.

crypt(3) is the library function which is used to compute a password hash. Technically the name is a misnomer since it is actually a cryptographic hash function. The output of the function is not merely the hash: it is a text string which also encodes the salt and identifies the hash algorithm used. Apache uses the traditional Unix crypt function with a randomly-generated 32-bit salt (only 12 bits used) and the first 8 characters of the password. ALG_CRYPT
MD5 is one in a series of message digest algorithms designed by Professor Ronald Rivest of MIT. The 128-bit (16-byte) MD5 hashes (also termed message digests) are typically represented as a sequence of 32 hexadecimal digits. In .htpasswd files the hash is: $apr1$ + an Apache-specific algorithm using an iterated (1,000 times) MD5 digest of various combinations of a random 32-bit salt and the password. ALG_APMD5
The SHA hash functions are a set of cryptographic hash functions designed by the National Security Agency (NSA) and published by the NIST as a U.S. Federal Information Processing Standard. SHA-1 produces a 160-bit digest from a message with a maximum length of (264 - 1) bits. SHA-1 is the most widely employed of the SHA family. It forms part of several widely used security applications and protocols, including TLS and SSL, PGP, SSH, S/MIME, and IPsec. In .htpasswd files the hash is as follows: {SHA} + Base64-encoded SHA-1 digest of the password. ALG_APSHA
Unencrypted for Windows, BEOS, & Netware only. ALG_PLAIN

Security Info

Web password files such as those managed by htpasswd should not be within the Web server's URI space -- that is, they should not be fetchable with a browser.

The SHA encryption format does not use salting: for a given password, there is only one encrypted representation. The crypt() and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult.

Basic Authentication

HTTP provides a simple challenge-response Access Authentication Framework mechanism that MAY be used by a server to challenge a client request and by a client to provide authentication information. It uses an extensible, case-insensitive token to identify the authentication scheme, followed by a comma-separated list of attribute-value pairs which carry the parameters necessary for achieving authentication via that scheme.

The 401 (Unauthorized) response message is used by an origin server to challenge the authorization of a user agent. This response MUST include a WWW-Authenticate header field containing at least one challenge applicable to the requested resource. The 407 (Proxy Authentication Required) response message is used by a proxy to challenge the authorization of a client and MUST include a Proxy- Authenticate header field containing at least one challenge applicable to the proxy for the requested resource.

Note: User agents will need to take special care in parsing the WWW- Authenticate or Proxy-Authenticate header field value if it contains more than one challenge, or if more than one WWW-Authenticate header field is provided, since the contents of a challenge may itself contain a comma-separated list of authentication parameters.

The realm directive (case-insensitive) is required for all authentication schemes that issue a challenge. The realm value (case-sensitive), in combination with the canonical root URL (the absoluteURI for the server whose abs_path is empty; see section 5.1.2 of [2]) of the server being accessed, defines the protection space. These realms allow the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme and/or authorization database. The realm value is a string, generally assigned by the origin server, which may have additional semantics specific to the authentication scheme. Note that there may be multiple challenges with the same auth-scheme but different realms.

A client SHOULD assume that all paths at or deeper than the depth of the last symbolic element in the path field of the Request-URI also are within the protection space specified by the Basic realm value of the current challenge. A client MAY preemptively send the corresponding Authorization header with requests for resources in that space without receipt of another challenge from the server. Similarly, when a client sends a request to a proxy, it may reuse a userid and password in the Proxy-Authorization header field without receiving another challenge from the proxy server. See section 4 for security considerations associated with Basic authentication.

A user agent that wishes to authenticate itself with an origin server--usually, but not necessarily, after receiving a 401 (Unauthorized)--MAY do so by including an Authorization header field with the request. A client that wishes to authenticate itself with a proxy--usually, but not necessarily, after receiving a 407 (Proxy Authentication Required)--MAY do so by including a Proxy- Authorization header field with the request. Both the Authorization field value and the Proxy-Authorization field value consist of credentials containing the authentication information of the client for the realm of the resource being requested. The user agent MUST choose to use one of the challenges with the strongest auth-scheme it understands and request credentials from the user based upon that challenge.

Note that many browsers will only recognize Basic and will require that it be the first auth-scheme presented. Servers should only include Basic if it is minimally acceptable.

The protection space determines the domain over which credentials can be automatically applied. If a prior request has been authorized, the same credentials MAY be reused for all other requests within that protection space for a period of time determined by the authentication scheme, parameters, and/or user preference. Unless otherwise defined by the authentication scheme, a single protection space cannot extend outside the scope of its server.

If the origin server does not wish to accept the credentials sent with a request, it SHOULD return a 401 (Unauthorized) response. The response MUST include a WWW-Authenticate header field containing at least one (possibly new) challenge applicable to the requested resource. If a proxy does not accept the credentials sent with a request, it SHOULD return a 407 (Proxy Authentication Required). The response MUST include a Proxy-Authenticate header field containing a (possibly new) challenge applicable to the proxy for the requested resource.

The HTTP protocol does not restrict applications to this simple challenge-response mechanism for access authentication. Additional mechanisms MAY be used, such as encryption at the transport level or via message encapsulation, and with additional header fields specifying authentication information. However, these additional mechanisms are not defined by this specification.

Proxies MUST be completely transparent regarding user agent authentication by origin servers. That is, they must forward the WWW-Authenticate and Authorization headers untouched, and follow the rules found in section 14.8. Both the Proxy-Authenticate and the Proxy-Authorization header fields are hop-by-hop headers.

Basic Authentication Scheme

The "basic" authentication scheme is based on the model that the client must authenticate itself with a user-ID and a password for each realm. The realm value should be considered an opaque string which can only be compared for equality with other realms on that server. The server will service the request only if it can validate the user-ID and password for the protection space of the Request-URI. There are no optional authentication parameters.

Upon receipt of an unauthorized request for a URI within the protection space, the origin server MAY respond with a challenge like the following:

WWW-Authenticate: Basic realm="PasswordProtected"

Where "PasswordProtected" is the string assigned by the server to identify the protection space of the Request-URI. A proxy may respond with the same challenge using the Proxy-Authenticate header field. To receive authorization, the client sends the userid and password, separated by a single colon (":") character, within a base64 [7] encoded string in the credentials.

basic-credentials = base64-user-pass base64-user-pass  =
<base64 [4] encoding of user-pass, except not limited to 76 char/line>
user-pass   = userid ":" password userid      = *
<text excluding ":">
password    = *TEXT

Userids might be case sensitive. If the user agent wishes to send the userid "Admin" and password "open sesame", it would use the following header field:

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

Misc htpasswd Messages

  • Failure file accesspermission problem
  • Failure command line syntax problem usage message issued
  • Failure password verification failure
  • Failure operation interrupted such as with CTRLC
  • Failure buffer would overflow username filename or computed too
  • Failure username contains illegal or reserved acters
  • Failure file is not a valid htpasswd file
htpasswd [-cmdpsD] passwordfile username
htpasswdb[cmdpsD] passwordfile username

htpasswdn[mdps] username
htpasswdnb[mdps] username password
c Create a new file.
n Dont update file display results on stdout.
m Force MD5 encryption of the password
d Force CRYPT encryption of the password
p Do not encrypt the password plaintext.
s Force SHA encryption of the password.

b Use the password from the command line rather than prompting for it.
D Delete the specified user.
  1. ALG_APMD5
username:password The file username:password does not appear
username:password cannot create file username:password
username:password cannot modify file username:password use -c to create it
username:password cannot open file username:password for
username:password could not determine temp dir
username:password unable to create temporary file username:password
username:password unable to read file username:password
username:password unable to update file username:password' pwfilename
username:password username contains illegal  acter $c arg BADUSER
username:password username:password
username:password record
APHTP_DELUSER We the user we were looking for. Add him to the file.
APHTP_NEWFILE APHTP_DELUSER username:passwordc andD options conflict
APHTP_NEWFILE APHTP_NOFILE username:passwordc andn options conflict
APHTP_NOFILE APHTP_DELUSER username:passwordn andD options conflict
All the file access checks any have been made. Time to go to work try to create the for the username in question. If that fails theres no need to waste any time on file manipulations. Any error message text is ed in the buffer since the mk routine doesnt have access to .
As it doesnt exist yet verify that we can create it.
CHARSET_EBCDIC algorithm user pwfilename password
CHARSET_EBCDIC xlate_open to_asci ISO-8859-1 DEFAULT_CHARSET
Check that this existing file is readable and writable.
Check to see the buffer is large enough to hold the username
Check to see the specified file can be opened for the given access.
Error outc was omitted for this non-existant file.
If were not creating a new file copy records from the existing one to the temporary file until we find the specified user.
If weve not got a colon on the line this could well not be a valid htpasswd file. We should bail at this point.
Lets do it. We end up doing a lot of file opening and closing but what do we care? This application isnt run antly.
MD5InitEBCDIC to_ascii
Make a password from the given information. A zero indicates success failure means that the output buffer contains an error message instead.
Make sure we still have exactly the right number of arguments left the filename the username and possibly the passwordb was specified.
On Windows NetWare and TPF systems the -m flag is used by  default.
On all other systems the -p flag will probably not work.
Only do the file checks were supposed to frob it.
PATH_MAX username:password filename too
SHA1InitEBCDIC to_ascii
SIZE_T_FMT  pwin
See this is our user.
The temporary file has all the data just copy it to the new location.
Updating  putline ftemp record
User username:password not  user
We can access the files the right way and we have a record to add or update. Lets do it..
We the user we were looking for. Delete them from the file.
28 sha1 s fixed len SHA
this len limitation is not in sync with any HTTPd len.
accessible pwfilename CREATE WRITE
accessible pwfilename READ APPEND
algorithm CRYPT algorithm APMD5 Automatically using MD5 format.
algorithm PLAIN Warning: storing passwords as plain text  might just not work on this platform.
algorithm user pwfilename
colon strchr scratch
crypt pw salt
existing_file APHTP_NEWFILE
existing_file CHARSET_EBCDIC xlate_t to_ascii
existing_file exists pwfilename
file_close fINVALID
file_copy pwfilename FILE_SOURCE_PERMS
file_mktemp ftemp SUCCESS
file_open fpw pwfilename READ BUFFERED
hash and delimiters.
md5_encode pw salt
mk user passwd
password_get New password:  pwin
password_get Re-type new password:  pwv
password for user username:password user
password pstrdup
password pwfilename user tn htpasswd.tmp.XXXXXX
password verification error
ps username:passwordusername:password tn
putline ftemp line
putline ftemp record
pwfilename pstrdup MAX_STRING_LEN username:password username too $d MAX_STRING_LEN
pwin pwv
pw passwd
readwrite access pwfilename
scratch cp[MAX_STRING_LEN]
sha1_base64 pw
sn password too
srand time time_t
temp_dir_get SUCCESS
to64 salt rand 8
to be a valid htpasswd file.
user pstrdup arg strchr user
user scratch

Htpasswd Links