UGent WebAuth

UGent WebAuth

Webauth is a central authentication service for UGent students and members of staff. Via webauth you can log on to different UGent webpages using your central password.

The direction ICT has a central passworddatabase at it's disposal, with the (encrypted) passwords of the users. By means of these passwords, users can authenticate at the login on servers, the reading of e-mail, the use of applications etc... Sometimes, a very critical application is involved, e.g. the score-input application. Since july 2000 DICT uses only safe encrypted protocols (SSH, IMAPs, HTTPs,...) for all network traffic in which passwords are transferred. Only in this way, it can be avoided that usable passwords might be intercepted.

Also other directions and faculty departments often have the need to authenticate users within their self-developed web applications on ther servers. For obvious reasons DICT can not supply the passwords to a third party. To make authentication possible by means of the central UGent passwords after all, the UGent WebAuth system was developed.

Webauth clients


Table of Contents

Principal functioning of UGent WebAuth
Security
Expansion
An example in Perl
An example concerning the key in Java

Principal functioning of UGent WebAuth

Assumed is an own webapplication myapp.pl with as URL http://mybox.UGent.be/cgi-bin/myapp.pl in which it is needed to have the authenticated identity of a user at disposal. The UGent WebAuth systeem consists in the making of an extra - static - page with, for example, the next content:

<html>
<body>
Klick 
<a href="https://webauth.UGent.be/?aid=A001&
url=http://mybox.UGent.be/cgi-bin/myapp.pl">here</a> for the application ! <br>
</body>
</html>

When a user clicks this hyperlink, then, the UGent WebAuth application on the machine webauth.UGent.be is called with the application ID (see lower) and the URL of the webapplication as arguments. The UGent WebAuth application is on the machine webauth.UGent.be in a directory to which access is controled by means of Basic Authentication using the following .htaccess file:

AuthType Basic
AuthName " UGent WebAuth "
AuthUserFile /etc/htpasswd
require valid-user

/etc/htpasswd contains the encrypted passwords of all users and is not readable for regular users on webauth.UGent.be (should they exist - the machine is only used for the UGent WebAuth application).

The user's access to the UGent WebAuth application is only granted after entering username and matching password. The so authenticated username is known within the UGent WebAuth application. Thereupon UGent WebAuth generates a HTML-page with roughly the next content:

<meta http-equiv="Refresh" content="0; 
URL=http://mybox.UGent.be/cgi-bin/myapp.pl?key=username">

In other words: the given own webapplication is called with the authenticated username as an argument. The application can read out the authenticated username by parsing the content of the environment-variable QUERY_STRING (cfr. CGI-protocol, method = GET)

Security

The mechanism as described higher is at least as unsafe as simple. Nothing stops a user to surf directly to the URL http://mybox.UGent.be/cgi-bin/myapp.pl?key=username for any chosen value as username.

The solution lies in the fact that UGent WebAuth encrypts the username by means of public/private key encryption. The public key can be generated from within the private key, but vice-versa this won't work: The private key can impossibly be found if only the public key is available. myapp.pl can use the public key ; only UGent WebAuth can use the private key. Data, encrypted with the private key can only be decrypted with the public key But also: when a cryptogram can be decrypted with the public key, than, it is certain that the corresponding private key was used at encryption. This property lies at the base of the digital signing of messages.

When UGent WebAuth encrypts the username by means of the private key, than, myapp.pl can decrypt it while certainty exists over the fact that the encryption happened by UGent WebAuth and nobody else. The public key can be downloaded from https://webauth.UGent.be/UGent.pub, or it can be copied from here:

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANEINsPFbISJtx0b23iiOj2y+gtx/pWf
4sbeGgZhn4eIUGMxI1+5UpJMT1Wh+fgqvhJzkv5O8G7S2rfjz6oKRxkCAwEAAQ==
-----END PUBLIC KEY-----

Of course, the cryptogram can be intercepted by a hacker and replayed over and over again to force access to myapp.pl

To avoid that the cryptogram is used more than once, UGent WebAuth will not only encrypt the username, but a string existing of the concatenation of the username, a serial number and an application ID (aid). The serial number is never the same. When the application myapp.pl notices that a cryptogram is offered more than once, then, access is denied. As serial a so called timestamp is used ; the number of seconds gone by since january first 1970 0:00h GMT. In this way, myapp.pl only has to manage a small list of recent used strings to check on repetitive use. Old strings can be rejected at a glance by means of the timestamp. The application ID is a free-to-choose 4-character string on which a check can be made afterwards. Doing so, the application can verify if the cryptogram is predestinated for it, and is not comming from a login-procedure at another application.

In this mechanism the cryptogram is passed through to the own application over the CGI protocol (as GET argument). In this, only a subset of the 7-bit ASCII character set can be used. That's why the cryptogram is passed through in Base64 encoding, on which the extra characters +, / and = are replaced by respectively *, - en .

So, UGent WebAuth generates a html page with as content:

<meta http-equiv="Refresh" content="0; URL=http://mybox.UGent.be/cgi-bin/myapp.pl?key=cryptogram">

Expansion

For a few applications it can come in handy to be able to pass through additional parameters to the own web application. This is permitted by UGent WebAuth. When you call your application by means of e.g. the URL

https://webauth.UGent.be/?aid=myAID&url=http://mybox.UGent.be/cgi-bin/myapp.pl& myParam1=myValue1&myParam2=myValue2

then UGent WebAuth generates a html page with as content:

<meta http-equiv="Refresh" content="0; 
URL=http://mybox.UGent.be/cgi-bin/myapp.pl?key=cryptogram&
myParam1=myValue1&myParam2=myValue2">

An obvious limitation in this is that the parameters may not have one of the following names: key, aid, url.

An example in php

https://catalpa.UGent.be/webauth_test/ is a simple webapplication (php-script) which prints the user's identity. Below the script's source code:

<?
$pubkey = openssl_get_publickey('file://ugent.pub') or die();

if (isset($_GET['key'])) {
    $ticket = $_GET['key'];
    $ticket = strtr($ticket,'*-.','+/=');
    $ticket = base64_decode($ticket);
    if (openssl_public_decrypt($ticket,$data,$pubkey)) {
        $_data = explode(":",$data);
        list($user,$time,$aid) = $_data;
    }
}

if (!$user) {
    header('Location: https://webauth.ugent.be/?url=https://catalpa.ugent.be/webauth_test/');
    exit();
}

header('Content-type: text/plain');

?>
user : '<?= $user ?>'
time : '<?= strftime('%Y/%m/%dT %H:%M:%S', $time) ?>'
aid  : '<?= $aid ?>'

An example in Perl.

The same example in Perl.

#! /usr/bin/perl

use CGI qw/:standard -no_xhtml/;
use MIME::Base64;

# http://perl-openssl.sourceforge.net/
use Crypt::OpenSSL::Random;
use Crypt::OpenSSL::RSA;

$key_string="-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANEINsPFbISJtx0b23iiOj2y+gtx/pWf
4sbeGgZhn4eIUGMxI1+5UpJMT1Wh+fgqvhJzkv5O8G7S2rfjz6oKRxkCAwEAAQ==
-----END PUBLIC KEY-----
";

$ticket = param("key");

if ($ticket ne "") {

    $ticket =~ s/\*/\+/g;
    $ticket =~ s/\-/\//g;
    $ticket =~ s/\./=/g;
    $ticket_d = decode_base64($ticket);

    $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($key_string);
    $rsa_pub->use_pkcs1_padding();
    $data = $rsa_pub->public_decrypt($ticket_d);
    @_data = split(":",$data);
    ($user,$time,$aid) = @_data;
}

if (!$user) {
    print redirect("https://webauth.ugent.be/?url=http://localhost/test.pl");
    exit;
}

print "Content-Type: text/html\n\n";

print "$user - $time - $aid\n";

An example concerning the key in Java

The action which makes the login is a struts action. Struts is a framework to develop web applications.
import org.apache.struts.action.*;
import java.security.interfaces.RSAPublicKey;
import java.security.Security;
import javax.crypto.*;
import java.io.*;
import org.bouncycastle.openssl.PEMReader;

public class DoWebAuthLoginAction extends Action {

   protected String action (ActionMapping mapping, ActionForm f,
        HttpServletRequest request, HttpSession session)
        throws Exception {
        // Get Key parameter from request
        String urlkey=request.getParameter ("key");
        System.out.println(urlkey);
        // Initialize org.apache.xml.security 
        org.apache.xml.security.Init.init();
        // Decode urlkey base 64 
        byte[]
urlout=org.apache.xml.security.utils.Base64.decode(translate(urlkey));
      
        // Read public key from file
        Security.addProvider(new
org.bouncycastle.jce.provider.BouncyCastleProvider());
        FileReader keyFile = new FileReader("UGent.pub");
        PEMReader kreader = new PEMReader(keyFile);
        RSAPublicKey key = (RSAPublicKey) kreader.readObject();
      
        // Decode key parameter to string of the 
form: Userid:Timestamp:applicationID
        Cipher c = Cipher.getInstance("RSA");
        c.init(Cipher.DECRYPT_MODE,key);
        byte[] decryptedText = c.doFinal(urlout);
        String msg = new String(decryptedText);
        System.out.println(msg);

       // Make this useful somewhere.

        return "succes";
}
Comments on the content: helpdesk@dict.UGent.be
Startpagina Helpdesk DICTHelpdesk DICT
University sites...

Dutch | Contact | Questions | Print | News