You are not logged in.

#1 2006-03-15 18:52:25

cmp
Member
Registered: 2005-01-03
Posts: 350

Paranoid Input

Hi.
I wrote this script, as secure way to input passwords if you trust the software, but don't trust the hardware (keyloggers).
It uses a internal random charmap,  assigning every printable ascii character (range 32 - 126) another random printable ascii character. every random character occurs only once.
to type your password you have to enter the key above your wanted character, to end the input just type enter.

Please let me know, what do you think? Is it secure?

TODO:
* replace the pseudo random number generator, with a real one
* find a way to let this program be used in pipes (it's merley a proof of concept)
* test it
* clean it up
* use a custom curses setup and don't rely on curses.wrapper

the script:

#!/usr/bin/env python

from random import shuffle
import curses

class Screen:
    """A very simple wrapper object for a curses screen"""
    
    def __init__(self, scr):
        self.scr = scr

    def putc(self, x,y, c, hl = True):
        if hl:
            self.scr.addch(y,x, c, curses.A_STANDOUT)
        else:
            self.scr.addch(y,x,c)
    
    def puts(self, x,y, s, hl = True):
        if hl:
            self.scr.addstr(y,x, s, curses.A_STANDOUT)
        else:
            self.scr.addstr(y,x,s)

    def getch(self):
        return self.scr.getch()

    def refresh(self):
        self.scr.refresh()

class KeyBoard:

    def __init__(self, scr):
        self.scr = scr
        self.charmap = range(32, 127)
        self.randomize()
        
    def randomize(self):
        shuffle(self.charmap)
    
    def at(self, x,y, rand = False):
        if rand:
            def uchr(i):
                return chr(self.charmap[i - 32]) 
        else:
            uchr = chr

        def line0(x, chr = uchr):
            return chr(97 + x)
        
        def line1(x):
            if x == 0 or x == 23:
                return uchr(32)
            if x == 1:
                return uchr(121)
            if x == 2:
                return uchr(122)
            if x == 21:
                return uchr(89)
            if x == 22:
                return uchr(90)

            if x >= 3 and x <12>= 13 and x <20>= 0 and x <6>= 7 and x <13>= 14 and x <19>= 20 and x <= 23:
                return uchr(x + 123 - 20)

        m = [line0, line1, line2, line4]
        return m[y](x)
    
    def decode(self, c):
        return chr(self.charmap.index(ord(c)) + 32)
    
    def draw(self):
        
        # layout:
        # first 24 lower chars
        # blank, y z Y Z 0-9 specialchars
        # first 24 upper chars
        # everything else
        
        for y in range(4):
            for x in range(24):
                self.scr.putc((x+x//8)*2,y*3, self.at(x,y))
                self.scr.putc((x+x//8)*2,y*3+1, self.at(x,y,True))



class Paranoia:

    def __init__(self, scr):
        self.scr = scr
        self.kb = KeyBoard(scr)
        self.result = ''
        
    def run(self):
        self.kb.draw()
        self.running = True
        while self.running:
            self.step()
            
        return self.result
            
    def step(self):
        
        c = self.scr.getch()
        
        if c == ord('n'):
            self.running = False
        
        if c in range(32, 127):
            self.result += self.kb.decode(chr(c))

        self.kb.randomize()
        self.kb.draw()

            
def main(stdscr):
    
    scr = Screen(stdscr)
    pi  = Paranoia(scr)
    
    return pi.run()
    
if __name__ == "__main__":
    res = curses.wrapper(main)
    print res

Offline

#2 2006-04-02 07:43:20

test1000
Member
Registered: 2005-04-03
Posts: 834

Re: Paranoid Input

heh, cool idea big_smile


KISS = "It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience." - Albert Einstein

Offline

Board footer

Powered by FluxBB