summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/ayk/jcryption.rb106
-rw-r--r--spec/jcryption.rb36
2 files changed, 142 insertions, 0 deletions
diff --git a/lib/ayk/jcryption.rb b/lib/ayk/jcryption.rb
new file mode 100644
index 0000000..ab60d34
--- /dev/null
+++ b/lib/ayk/jcryption.rb
@@ -0,0 +1,106 @@
+#! /usr/bin/env ruby
+# -*- coding: UTF-8 -*-
+
+#----------------------------------------------------------------------------
+#
+# File : jcryption.rb
+# Author : Jérémy Zurcher <jeremy@asynk.ch>
+# Date : 11/09/09
+# License :
+#
+# Copyright (c) 2009 Jérémy Zurcher
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+#----------------------------------------------------------------------------
+#
+def Math.power_modulo(b, p, m)
+ if p == 1
+ b % m
+ elsif (p & 0x1) == 0
+ t = power_modulo(b, p >> 1, m)
+ (t * t) % m
+ else
+ (b * power_modulo(b, p-1, m)) % m
+ end
+end
+#
+class Bignum
+ #
+ class << self
+ def from_bytes bytes
+ val = 0
+ idx = 0
+ bytes.each_byte{ |b|
+ val += b << 8 * idx
+ idx += 1
+ }
+ val
+ end
+ end
+ #
+ def to_bytes
+ str = ''
+ bint = self
+ while bint!=0 do
+ bint,r = bint.divmod 256
+ str += r.chr
+ end
+ str
+ end
+ #
+ def bits
+ s = self.to_bytes
+ while s[-1].ord==0
+ s.slice!(-1)
+ end
+ bit_len = s.length * 8
+ tmp = s[-1].ord
+ while not tmp & 0x80
+ bit_len-=1
+ tmp <<=1
+ end
+ bit_len
+ end
+end
+#
+module JCryption
+ #
+ def decrypt data, d, n
+ s = data.split(' ').inject('') do |str,block| str += ( Math::power_modulo( block.to_i(16), d, n ) ).to_bytes end
+ sum,crc = 0,s.slice(0,2).to_i(16)
+ s.slice(2..-1).each_char do |char| sum += char.ord end
+ return ( crc == sum & 0xFF ) ? s : nil
+ end
+ module_function :decrypt
+ #
+ def rsa_keys key, len
+ '{"e":"'+key.e.to_s(16)+'","n":"'+key.n.to_s(16)+'","maxdigits":"'+(len*2/16+3).to_s+'"}'
+ end
+ module_function :rsa_keys
+ #
+ def gen_keypair bits
+ # therese no point to try without using openssl
+ require 'openssl'
+ OpenSSL::PKey::RSA.generate( bits )
+ end
+ module_function :gen_keypair
+end
+
diff --git a/spec/jcryption.rb b/spec/jcryption.rb
new file mode 100644
index 0000000..a974ea1
--- /dev/null
+++ b/spec/jcryption.rb
@@ -0,0 +1,36 @@
+#! /usr/bin/env ruby
+# -*- coding: UTF-8 -*-
+
+require 'ayk/jcryption'
+#
+describe JCryption do
+ #
+ describe 'Bignum' do
+ it '#to_bytes #from_bytes should work' do
+ 0x217962755220666f207463657073612074656577732061207369206d756e676942.should eql Bignum.from_bytes(0x217962755220666f207463657073612074656577732061207369206d756e676942.to_bytes)
+ end
+ it '#bits' do
+ K_BITS = 1024
+ k = JCryption.gen_keypair( K_BITS )
+ k.n.to_i.bits.should eql k.d.to_i.bits
+ k.d.to_i.bits.should eql k.d.to_i.bits
+ k.d.to_i.bits.should eql K_BITS
+ k.p.to_i.bits.should eql k.q.to_i.bits
+ k.q.to_i.bits.should eql k.q.to_i.bits
+ k.q.to_i.bits.should eql K_BITS/2
+ end
+ end
+ #
+ describe 'JCryption' do
+ it 'should decrypt data' do
+ data = '50c412c556a9fab55b50bd0d989067b341f9cdbf12ccb65aeb69dbb360a8e0dbd2069d686873b659b1be7a4c78fe631d362dbf538a5298ecaff19f78cd859897a7317c71b51b90e0a8c03e10059b68826bfeb194a4339a0ecc4a571ba9066fcf3504ffe76e07468cbe03337d3cfebd4efe687f5da72bf694dada987cea884180 ac07cc8462ce0f3e23dafe5d19f47eb33024c91de48413a971bf3b88c159090a26933f694d868bad61517a817f57998ed57bcebcd46a4ed8661cec3e24a8cdf21595902c2fd566820382e2d4f2ee7f1f11fa87a760bcecdf46282147d2c3a1afed3797d22296abcc3b1289489e7c265b3b4223bf93cbf0bb5122c021501a4305'
+ d = 142955580847936812437193870755035814405124627347905842843339476660410062601811480700441889718210202009243007436072050916187661826876350920486486397010450730779696290631486871265879746303575786048408069636369193884693458677811152828648243101513361320608836252500169104146911809960770571514285315905292345077217
+ n = 144356479900636891214255168759692179915080702955265792860263158994365175771327391113617049451662409039610467917872667615201472907166228721836687554904761268852157980063791071632316452235833332213934315100709197309374114347503598139080114451506623646859901230057693420846126487025125157251928362812236904436763
+ h = JCryption::decrypt( data, d, n).split('&').inject({}) { |h_,vk| v,k = vk.split '='; h_[v]=k; h_ }
+ h['username'].should eql "my_username"
+ h['passwd'].should eql "my_password"
+ h['timestamp'].should eql "1252937955"
+ end
+ end
+end
+#