cancel
Showing results for 
Search instead for 
Did you mean: 

Encrypting data in repository

tim91
Champ in-the-making
Champ in-the-making
Hi,

I hope that this is right place to wrote this post.

I extended few classes called ContentServiceImpl, FileContentStore, FileContentReader and FileContentWriter.

In my new classes called EnryptedContentReader and EnryptedContentWriter i am grabbing data stream in overrided methods and i encrypt/decrypt it.

If file is only encrypted i can download it without problem and file is encrypted (file encrypts and everything is fine).

Problem is when i am trying download file and decrypt it, in method  getContent(OutputStream os) (method from class AbstractContentReader) that i am overriding, i am doing something like this.


        @Override
   public void getContent(OutputStream os) throws ContentIOException {

      if (!decrypt) {  //i am checking if i must decrypt file
         try
           {
               InputStream is = getContentInputStream();
               os.flush();
               FileCopyUtils.copy(is, os);  // both streams are closed
               // done
           }
           catch (IOException e)
           {
               throw new ContentIOException("Failed to copy content to output stream: \n" +
                       "   accessor: " + this,
                       e);
           }
      } else {
            decryptDuringCopy(os);
      }
   }

   public void decryptDuringCopy(OutputStream os){
      InputStream is = null;
      CipherInputStream cis = null;
       try
       {
          is = getContentInputStream();
           os.flush();
            AESManager am = new AESManager();
            Cipher cipher = null;
         try {
            cipher = am.getCipherDecrypt(key.getBytes("UTF-8"));
         } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
            cis = new CipherInputStream(is, cipher);
            byte[] data = new byte[1024];
            int read = cis.read(data);
            int readed = read;
            while (read != -1) {
                os.write(data, 0, read);
                read = cis.read(data);
                readed += read;
            }
           
       }
       catch (IOException e)
       {
           throw new ContentIOException("Failed to copy content to output stream: \n" +
                   "   accessor: " + this,
                   e);
       } finally {
           try {
              os.flush();
            os.close();
         } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
           try {
            is.close();
         } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
           try {
            cis.close();
         } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
       }
   }


Problem is strange because file is downloading but when all bytes was copied into OutputStream, in browser i have 99% of download and i must wait about 10sec to process ending. After download, file is correctly decrypted. It look like in alfresco is turning sleep method after copying all bytes. I am wondering if maybe browser is checking checksum ( file that is downloaded is decrypted and is different to file that was stored in repository ).
I don't have any idea what is wrong

Sorry for my engilsh.

Edit:
I connected to alfresco using ftp, after download total commander says "Downloading error" but after pressing "OK", i can open file and everything is fine. 
2 REPLIES 2

hr61369256
Champ in-the-making
Champ in-the-making
Hi tim91,

I've a couple of questions to your encryption and decryption process: where exactly does the encryption/decryption take place? Do I understand you right, when you extend existing classes on server-side, the encryption/decryption is running on server-side? What about content transmission from server to client and vise versa?

May be that I misunderstood something.

Thanks, Ralf

tim91
Champ in-the-making
Champ in-the-making
Thanks for Your reply.

Process of encrypting and decrypting is on server side.
During transmission file to the server content is encrypting in overloaded method called copyStreams with oryginal is stored in class org.alfresco.repo.content.AbstractContentWriter

<java>
@Override
   public int copyStreams(InputStream in, OutputStream out) throws IOException {
      
      AESManager manager = new AESManager();
      
      int bytesReaded = manager.encrypt(in, out, encryptionKey.getBytes("UTF-8"));
      
      return bytesReaded;
      
   }
</java>

As You can see i am grabbing inputStream and in method encrypt i am encrypting stream and saving it in outputStream.

Problem is as i wrote with downloading file, i am using this code, oryginal method is stored in class org.alfresco.repo.content.filestore.FileContentReader

<java>
@Override
    protected ReadableByteChannel getDirectReadableChannel() throws ContentIOException
    {
        try
        {
            // the file must exist
            if (!file.exists())
            {
                throw new IOException("File does not exist: " + file);
            }
            ReadableByteChannel channel = null;
           
           
           
            if( !decrypt ){
               if (allowRandomAccess)
                {
                    RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");  // won't create it
                    channel = randomAccessFile.getChannel();
                }
                else
                {
                    InputStream is = new FileInputStream(file);
                    channel = Channels.newChannel(is);
                }
            }
            else{
               AESManager am = new AESManager();
                byte[] c = am.decrypt(file, null, "!qazXsw2!@#$".getBytes());
                ByteArrayInputStream is = new ByteArrayInputStream©;
                channel = Channels.newChannel(is);
            }
           
            // done
            if (logger.isDebugEnabled())
            {
                logger.debug("Opened read channel to file: \n" +
                        "   file: " + file + "\n" +
                        "   random-access: " + allowRandomAccess);
            }
            return channel;
        }
        catch (Throwable e)
        {
            throw new ContentIOException("Failed to open file channel: " + this, e);
        }
    }
</java>

I tried downloading file using CMIS service and i got error because length of stream was different(decrypting process is decreasing content length), after decryption process size of file is smaller and i am wondering if this isn't reason that this solution doesn't work.
I don't know where grab information about file length and change it.

Maybe now what i am trying to do is more clear.

Regards, Tim91