Analisis Dan Perancangan Sistem Autentikasi Pengguna Pada Web Menggunakan Metode Multiple-Key Rsa
LISTING PROGRAM
1. Module rsa_multiple_key.py
# -*- coding: utf-8 -*- """ rsa_multiple_key.py ~~~~~~~~~~~~~~ A Multiple-Key RSA library using Miller-Rabin Primality Test and Gordon's Algorithm to generate Strong Primes for Author`s Undergraduate Theses.
""" import random, math, sys, fractions import itertools, time, ast, string, os def generateKey(bit): p = generateStrongPrime(bit) q = generateStrongPrime(bit) while q == p: q = generateStrongPrime(bit); totien_n = (p - 1) * (q - 1) n = p * q return p, q, totien_n, n def getKdKe(t, totien_n): Ke = [] Kd = [] for i in range(0, t): if i == 0: while True: e = random.randint(2, (totien_n - 1)) if fractions.gcd(totien_n, e) == 1: break else: multKeyE = 1 for x in range(0, i): multKeyE *= Ke[x] while True: e = random.randint(2, (totien_n - 1)) if fractions.gcd(totien_n, multKeyE * e) == 1: break
Ke.append(e) Kd.append(invMod(e, totien_n)) return Ke, Kd def generateRandomPrime(bit): """Generate Random Algorithm""" digit = bit / 8 n = random.randint(pow(10, digit - 1), pow(10, digit) - 1) // 2 * 2 + 1 while not isPrime(n): n = random.randint(pow(10, digit - 1), pow(10, digit) - 1) // 2 * 2 + 1 return n def generateStrongPrime(bit): """Generate Strong Prime with Gordon's Algorithm""" n = bit / 2 r = generateRandomPrime(n) s = generateRandomPrime(n) while s == r: s = generateRandomPrime(n) j = 1 p = 0 q = 2 * j * s + 1 while not MillerRabin(q): q = 2 * j * s + 1 j += 1 p0 = pow(r, (q - 1), (r * q)) - pow(q, (r - 1), (r * q)) + r * q p0 = p0 % (r * q) if p0 & 1 == 0: return GordonStrongPrime(bit) j = 1 p = 2 * j * q * r + p0 while not MillerRabin(q): p = 2 * j * q * r + p0 j += 1 return p def isPrime(n): lowPrimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61, 67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157, 163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251, 257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353, 359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457, 461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571, 577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673, 677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797, 809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911, 919,929,937,941,947,953,967,971,977,983,991,997] if n in lowPrimes: return True elif n & 1 != 0: return MillerRabin(n) return False def MillerRabin(n): u = n - 1 t = 0 while u & 1 == 0: u /= 2 t += 1 def witness(a): x = [] x.append(pow(a, u, n)) for i in range(1, t+1): x.append(pow(x[i-1], 2, n)) if x[i] == 1 and x[i-1] != 1 and x[i-1] != n - 1: return True if x[t] != 1: return True return False for i in range(len(str(n))): a = random.randint(2, n - 1)
if witness(a): return False return True def invMod(a, m): """Inverse Mod with Extended Euclid"""g, x, y = extended_gcd(a, m) return x % m def extended_gcd(aa, bb): """Iterative Extended gcd""" lastremainder, remainder = abs(aa), abs(bb) x, lastx, y, lasty = 0, 1, 1, 0 while remainder: lastremainder, (quotient, remainder) = remainder, divmod(lastremainder, remainder) x, lastx = lastx - quotient*x, x y, lasty = lasty - quotient*y, y return lastremainder, lastx * (-1 if aa < 0 else 1), lasty * (-1 if bb < 0 else 1) def encrypt(Pt, n, e): C = [] for i in range(0, len(Pt)): C.append(pow(ord(Pt[i]), e, n)) return C def decrypt(C, n, d): P = [] for i in range(0, len(C)): P.append(chr(pow(C[i], d, n))) return P
2. Module run.py
# -*- coding: utf-8 -*- """ run.py ~~~~~~~~~~~~~~ A web portal that implemented Multiple-Key RSA for Author`s Undergraduate Theses.
""" from flask import * from functools import wraps import pymongo, datetime, json, ast import rsa_multiple_key as rsa import random, string, os, unicodedata app = Flask(__name__) app.config.from_object(__name__) app.secret_key = '92%&*$7fuN' def Connect2DB(): con = pymongo.MongoClient() return con.rsa
@app.route('/', methods=['GET', 'POST']) @app.route('/login', methods=['GET', 'POST']) @app.route('/index', methods=['GET', 'POST']) def index(): """This is main page with login purpose""" error = None if 'logged_in' in session: users_list = getUsersList() return render_template('status.html', users_list=users_list, user=session['logged_in']) elif request.method == 'POST' and "username" in request.form: uname = request.form['username'] if doLogin(uname, request.form['password']): session['logged_in'] = uname return redirect(url_for('status')) else: error = 'Invalid credentials. Please try again.' return render_template('index.html', error=error) def doLogin(username, password): try: db = Connect2DB() user = db.users.find_one({'_id':username}) key = db.keys.find_one() pwd = rsa.encrypt(password, int(key['n']), int(user['Ke'])) if str(pwd) == user['pass']: return True else: return False finally: pass def required_roles(*roles): def wrapper(f): @wraps(f) def wrapped(*args, **kwargs): if get_current_user_role() not in roles: flash('You don\'t have any sufficient credentials.') return redirect(url_for('index')) return f(*args, **kwargs) return wrapped return wrapper def get_current_user_role(): try: if session['logged_in'] == 'admin': return 'admin' elif isAllUsers(): return 'admin' else: return 'user' except: return 'anon' def isAllUsers(): """Check online users is all users.""" try: db = Connect2DB() loggedInUsers = [] allUsers = [] for user in db.users.find(): if str(user['_id']) != 'admin': allUsers.append(str(user['_id'])) for user in db.user_log.find(): name = str(user['username']) if name not in loggedInUsers and name != 'admin': loggedInUsers.append(name) if Counter(allUsers) == Counter(loggedInUsers): return True else: return False finally: pass
@app.route('/logout') def logout(): session.pop('logged_in', None) flash('You were logged out') return redirect(url_for('index')) @app.route('/status') @required_roles('admin', 'user') def status(): """Display users (on/off)line status""" users_list = getUsersList() return render_template('status.html', users_list=users_list, user=session['logged_in']) @app.route('/check', methods=['GET']) @required_roles('admin', 'user') def check(): """Check users online status""" data = [] user = request.args.get('echoValue') reset_log = datetime.timedelta(seconds=30) userLists = getUsersList().remove('admin') try: db = Connect2DB() stamp = datetime.datetime.utcnow() timeout = stamp - reset_log db.user_log.insert({'username':str(user), 'stamp':stamp}) for log in db.user_log.find({'stamp': { '$lt': timeout }}): db.user_log.remove(log) onlineUser = db.user_log.find() for user in onlineUser: name = user['username'] if name not in data: data.append(name) return jsonify(result=data) except: pass def getUsersList(): UsersList = [] try: db = Connect2DB() for user in db.users.find(): UsersList.append(str(user['_id'])) return UsersList finally: pass @app.route('/setting', methods=['GET', 'POST']) @required_roles('admin', 'user') def setting(): """Allows users to change their password""" error = None if request.method == 'POST' and "password" in request.form: if doSetting(session['logged_in'], request.form['password']): return redirect(url_for('setting')) else: error = 'An error has been occured. Please try again.' return render_template('setting.html', error=error) def doSetting(uname, passwd): try: db = Connect2DB() user = db.users.find_one({'_id':uname}) key = db.keys.find_one() pwd = rsa.encrypt(passwd, int(key['n']), int(user['Ke'])) db.users.update({"_id":uname}, {"pass":str(pwd), "Ke":str(user['Ke']), "Kd":str(user['Kd'])}) return True except: return False @app.route('/reset', methods=['GET', 'POST']) @required_roles('admin') def reset(): """Allows super user to reset users and their password""" error = None if request.method == 'POST' and "password" in request.form and request.form['btn'] == "Reset": x, y = doReset('admin', request.form['password'], request.form['users']) if x: return render_template('reset.html', allUsers=y) else: error = y return render_template('reset.html', error=error) def doReset(uname, passwd, users): """Reset all users and it's settings""" db = Connect2DB() user = db.users.find_one({'_id':uname}) key = db.keys.find_one() pwd = rsa.encrypt(passwd, int(key['n']), int(user['Ke'])) if str(pwd) == user['pass']: pwdAdmin = rsa.decrypt(pwd, int(key['n']), int(user['Kd'])) t = int(users) p, q, totien_n, n = rsa.generateKey(512) Ke, Kd = rsa.getKdKe(t, totien_n) e = 1 d = 1 nUser = {} for user in db.users.find(): db.users.remove(user) for key in db.keys.find(): db.keys.remove(key) for x in range(0, t): rPass = randomPass(8) password = rsa.encrypt(rPass, n, Ke[x]) name = 'user'+str(x) db.users.insert({'_id':name, 'pass':str(password),
'Kd':str(Kd[x]), 'Ke':str(Ke[x])}) e *= Ke[x] d *= Kd[x] nUser[name] = rPass db.users.insert({'_id':'admin', 'pass':str(rsa.encrypt(pwdAdmin, n, e)), 'Kd':str(d), 'Ke':str(e)}) db.keys.insert({'p':str(p), 'q':str(q), 'n':str(n), 'tot_n':str(totien_n)}) return True, nUser else: return False, 'Your password is not match.' def randomPass(length): """generate random password""" chars = string.ascii_letters + string.digits + '!@#$%^&*()' random.seed = (os.urandom(1024)) return ''.join(random.choice(chars) for i in range(length)) @app.route('/system') @required_roles('admin') def system(): return render_template('system.html') @app.route('/about') def about(): return render_template('about.html') @app.route('/contact') def contact(): return render_template('contact.html') @app.errorhandler(404) def page_not_found(error): session['redirected_from'] = request.url return render_template('404.html'), 404 if __name__ == '__main__': app.run(debug=True)
3. template.html
<!doctype html> <html> <head> <title>RSA Multiple Key</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}"> <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> <script src="{{ url_for('static', filename='jquery-1.9.1.min.js') }}"></script> <script type=text/javascript>var $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};</script> </head> <body> <div class="container darkbg clearfix"> <div id="headercont" class="clearfix"> <div id="headerlogo"> <h1><a title="" href="">Authentication System</a></h1> </div>
<div id="headerright"> <p><span>Author:</span> Fauzana S</p> <p><span>Student ID:</span> 091401031</p> </div> </div> </div> <div class="container lightbluebg clearfix"> <div id="menucont" class="clearfix"> <div class="menu"> <ul> <li class="active"><a title="Home" href="/">Home</a></li> <li><a title="" href="/about">About</a></li> <li><a title="Contact" href="/contact">Contact</a></li> </ul> </div> </div> </div> <div class="container clearfix"> <div id="maincont" class="clearfix"> {% for message in get_flashed_messages() %}<div class=flash>{{ message }}</div>{% endfor %}<div id="mainleft"> {% block content %} {% endblock %} <div class="sidecont clearfix"> <div class="sidesection clearfix"> <h4><a title="" href="#">Description</a></h4> <div class="sidetop"> <a class="hoverlink" title="" href="#"><img alt="" src="/static/side- 1.jpg" /><div class="overlay link"></div></a> </div> <div class="sidebottom"> <p>Multiple Key RSA Implementation for Author's Undergraduate Theses</p> </div> </div> <div class="sidesection clearfix"> <h4><a title="" href="#">Institution</a></h4> <div class="sidetop"> <a class="hoverlink" title="" href="#"><img alt="" src="/static/side- 2.jpg" /><div class="overlay link"></div></a> </div> <div class="sidebottom"> <p>Universitas Sumatera Utara</p> </div> </div> </div> </div> </div> </div> <div class="container clearfix"> <div id="footercont" class="clearfix"> <p>Multiple Key RSA &copy;&copy; 2013 - by <a title="fauzana s" href="http://twitter.com/__fauzana__" rel="external">Fauzana S</a></p> </div> </div> </body> </html>
4. index.html
{% extends "template.html" %}{% block content %}<h1>Welcome</h1> <p>This is "..." web page portal. It's the greatest webpage there is.<br><br>Just try clicking on things to the left, you have to log in though. Do you think you have access? I doubt you can guess my password.
<h3>Login is required:</h3> {% if error %}<p class=error><strong>Error:</strong>{{ error }}{% endif %} <form action="" method=post> <dl> <dt>Username: <dd><input type=text name=username value="{{ request.form.username }}"> <dt>Password: <dd><input type=password name=password> </dl> <p><input type=submit value=Login> </form> </div> <div id="mainright"> <h3>Other Links</h3> <ul class="otherlinks clearfix"> <li><a title="log in into system" href="/login">Login</a></li> </ul>{% endblock %}
5. status.html
{% extends "template.html" %}{% block content %} <h1>Log In Status</h1> <script type=text/javascript> setInterval(function(){ $.getJSON($SCRIPT_ROOT + '/check', { echoValue: $('#me').text() }, function(data) { $(".red").css({"color": "#C00"}); for (var i in data.result) { document.getElementById(data.result[i]).style['color']="#00C"; } } ); return false; },2000); </script> <h2>Welcome, <span id="me">{{ user }}</span>!</h2> <div class="users-log"> <h5>Logged in user: [<span style="color: #00C;">&#10041;</span>], otherwise not.</h5> {% for u in users_list %}<p>[<span class="red" id="{{ u }}" style="color: #C00">&#10041;</span>] {{ u }} {% endfor %}<p id="test"> </div> </div> <div id="mainright"> <h3>Other Links</h3> <ul class="otherlinks clearfix">
<li><a title="log out from system" href="/logout">Logout</a></li> <li><a title="change password" href="/setting">Setting</a></li> <li><a title="reset all users" href="/reset">Reset</a></li> <li><a title="system core" href="/system">System</a></li> </ul>{% endblock %}
5. setting.html
{% extends "template.html" %}{% block content %}<h1>Welcome User!</h1> <p>Bored? Need a password change? {% if error %}<p class=error><strong>Error:</strong>{{ error }}{% endif %} <form action="" method=post> <dl> <dt>New Password: <dd><input type=password name=password> <dd><input type=submit value=Submit> </dl> </form> </div> <div id="mainright"> <h3>Other Links</h3> <ul class="otherlinks clearfix"> <li><a title="log out from system" href="/logout">Logout</a></li> <li><a title="find users status" href="/status">Status</a></li> <li><a title="reset all users" href="/reset">Reset</a></li> <li><a title="system core" href="/system">System</a></li> </ul>{% endblock %}
6. system.html
{% extends "template.html" %}{% block content %}<h1>System</h1> <p>Make a decision?<br>Memorandum?<br>Agreement?<br>Conspiracy?<br>.....<br>...
..<br>....., etc. </div> <div id="mainright"> <h3>Other Links</h3> <ul class="otherlinks clearfix"> <li><a title="log out from system" href="/logout">Logout</a></li> <li><a title="find users status" href="/status">Status</a></li> <li><a title="change password" href="/setting">Setting</a></li> <li><a title="reset all users" href="/reset">Reset</a></li> </ul>{% endblock %}
7. reset.html
{% extends "template.html" %}{% block content %}<h1>Welcome Super User!</h1> <p>Bored? Need a change? F5? {% if error %}<p class=error><strong>Error:</strong>{{ error }}{% endif %} <h3>Reset</h3> <p>Reset all users config? Sure?
<div class="spoiler"> <form action="{{ url_for('reset') }}" method=post> <dl> <dt>Users total: <dd><input type=text name=users> <dt><i>Super user</i> password: <dd><input type=password name=password> <dd><input type=submit name=btn value=Reset> </dl> </form> </div> {% if allUsers %} <div class="warning"> <p>Warning: Please save this credentials in <strong>safe</strong> place, it's only show <strong>once</strong>.
<ol> {% for k in allUsers %} <li>{{ k }} : {{ allUsers[k] }}</li> {% endfor %} </ol> </div>{% endif %} </div> <div id="mainright"> <h3>Other Links</h3> <ul class="otherlinks clearfix"> <li><a title="log out from system" href="/logout">Logout</a></li> <li><a title="find users status" href="/status">Status</a></li> <li><a title="change password" href="/setting">Setting</a></li> <li><a title="system core" href="/system">System</a></li> </ul>{% endblock %}
8. 404.html
{% extends "template.html" %}{% block content %}<h1>Page not found!</h1> <p>I don't know where you were trying to go, but it's not there. </div> <div id="mainright"> <h3>Other Links</h3> <ul class="otherlinks clearfix"> <li><a title="log in into system" href="/">Login</a></li> </ul>{% endblock %}
9. contact.html
{% extends "template.html" %}{% block content %}<h1>Contact</h1> <p>To contact me, click your heels together three times. </div> <div id="mainright"> <h3>Other Links</h3> <ul class="otherlinks clearfix"> <li><a title="log in into system" href="/">Login</a></li> </ul>{% endblock %}
10. about.html
{% extends "template.html" %}{% block content %}<h1>About</h1> <p>My name is Nana and I am Python ninja!. </div> <div id="mainright"> <h3>Other Links</h3> <ul class="otherlinks clearfix"> <li><a title="log in into system" href="/">Login</a></li> </ul>{% endblock %}
Fauzana S 0812 60 27 67 92 ☎
Jl. Sisingamangaraja km. 11.5 Komp. Riviera Blok NC 6, Amplas, Medan, Sumatera Utara [email protected] ✉
Pendidikan 2009 – 2013 S1 Ilmu Komputer Fasilkom-TI USU, Medan.
2003 – 2009 Pondok Pesantren Modern Nurul Ikhlas, Tanah Datar.
1997 – 2003 SDN 173651 Pintu Pohan, Toba Samosir.
Keahlian Bahasa Indonesia, Inggris, Arab.
Bahasa Pemrograman Python, PHP, C# .NET, C++, Java, JavaScript, VB .NET.
Database MySQL, MongoDB, Oracle, MS-SQL.
Version Control System Git, Subversion.