Module: Crypt::CBC
Overview
cbc.rb Richard Kernahan
Constant Summary collapse
- ULONG =
0x100000000
Instance Method Summary collapse
- #carefully_open_file(filename, mode) ⇒ Object
- #decrypt_file(cryptFilename, plainFilename) ⇒ Object
- #decrypt_stream(cryptStream, plainStream) ⇒ Object
- #decrypt_string(cryptText) ⇒ Object
- #encrypt_file(plainFilename, cryptFilename) ⇒ Object
- #encrypt_stream(plainStream, cryptStream) ⇒ Object
- #encrypt_string(plainText) ⇒ Object
- #generate_initialization_vector(words) ⇒ Object
Instance Method Details
#carefully_open_file(filename, mode) ⇒ Object
73 74 75 76 77 78 79 80 81 82 |
# File 'lib/crypt/cbc.rb', line 73 def carefully_open_file(filename, mode) begin aFile = File.new(filename, mode) rescue puts "Sorry. There was a problem opening the file <#{filename}>." aFile.close() unless aFile.nil? || aFile.closed? raise end return(aFile) end |
#decrypt_file(cryptFilename, plainFilename) ⇒ Object
94 95 96 97 98 99 100 |
# File 'lib/crypt/cbc.rb', line 94 def decrypt_file(cryptFilename, plainFilename) cryptFile = carefully_open_file(cryptFilename, 'rb') plainFile = carefully_open_file(plainFilename, 'wb+') decrypt_stream(cryptFile, plainFile) cryptFile.close unless cryptFile.closed? plainFile.close unless plainFile.closed? end |
#decrypt_stream(cryptStream, plainStream) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/crypt/cbc.rb', line 56 def decrypt_stream(cryptStream, plainStream) # Cypher-block-chain mode chain = cryptStream.read(block_size()) while (block = cryptStream.read(block_size())) decrypted = decrypt_block(block) plainText = decrypted ^ chain plainStream.write(plainText) unless cryptStream.eof? chain = block end # write the final block, omitting the padding buffer = plainText.split('') remainingMessageBytes = buffer.last.unpack('C').first remainingMessageBytes.times { plainStream.write(buffer.shift) } end |
#decrypt_string(cryptText) ⇒ Object
112 113 114 115 116 117 118 |
# File 'lib/crypt/cbc.rb', line 112 def decrypt_string(cryptText) cryptStream = StringIO.new(cryptText) plainStream = StringIO.new('') decrypt_stream(cryptStream, plainStream) plainText = plainStream.string return(plainText) end |
#encrypt_file(plainFilename, cryptFilename) ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/crypt/cbc.rb', line 85 def encrypt_file(plainFilename, cryptFilename) plainFile = carefully_open_file(plainFilename, 'rb') cryptFile = carefully_open_file(cryptFilename, 'wb+') encrypt_stream(plainFile, cryptFile) plainFile.close unless plainFile.closed? cryptFile.close unless cryptFile.closed? end |
#encrypt_stream(plainStream, cryptStream) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/crypt/cbc.rb', line 26 def encrypt_stream(plainStream, cryptStream) # Cypher-block-chain mode initVector = generate_initialization_vector(block_size() / 4) chain = encrypt_block(initVector) cryptStream.write(chain) while ((block = plainStream.read(block_size())) && (block.length == block_size())) block = block ^ chain encrypted = encrypt_block(block) cryptStream.write(encrypted) chain = encrypted end # write the final block # At most block_size()-1 bytes can be part of the message. # That means the final byte can be used to store the number of meaningful # bytes in the final block block = '' if block.nil? buffer = block.split('') remainingMessageBytes = buffer.length # we use 7-bit characters to avoid possible strange behavior on the Mac remainingMessageBytes.upto(block_size()-2) { buffer << rand(128).chr } buffer << remainingMessageBytes.chr block = buffer.join('') block = block ^ chain encrypted = encrypt_block(block) cryptStream.write(encrypted) end |
#encrypt_string(plainText) ⇒ Object
103 104 105 106 107 108 109 |
# File 'lib/crypt/cbc.rb', line 103 def encrypt_string(plainText) plainStream = StringIO.new(plainText) cryptStream = StringIO.new('') encrypt_stream(plainStream, cryptStream) cryptText = cryptStream.string return(cryptText) end |
#generate_initialization_vector(words) ⇒ Object
16 17 18 19 20 21 22 23 |
# File 'lib/crypt/cbc.rb', line 16 def generate_initialization_vector(words) srand(Time.now.to_i) vector = "".force_encoding("ASCII-8BIT") # stop ruby 2 using Unicode words.times { vector << [rand(ULONG)].pack('N') } return(vector) end |