function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
LabrixLabrix 

Amazon S3 Image Links fail about 50% of the time

My Company is attempting to use Amazon S3 for storage of various image files that need to be kept secure.  To do this we have setup Amazon's s3 service with an encrypted key security system.  This system fails about 50% of the time for some unknown reason that we think is to do with the clocks at Amazon and Sales-force being slightly off.  

 

We would like to know why our system is failing sometimes (producing broken image links) and if their is a simple fix to allow the passthrough to work.

 

Code:

 

    public static String GenerateAWSLink(Boolean isFront, String barcode){
    	String bucketName = '';
    	String fileName = '';
    	if(isFront){
    		bucketName = 'front_' + AWSAmazonS3.key.toLowerCase();
    		fileName = barcode.toUpperCase() + '_front.jpg';
    	}
    	else{
    		bucketName = 'back_' + AWSAmazonS3.key.toLowerCase();
    		fileName = barcode.toUpperCase() + '_back.jpg';
    	}

        fileName = EncodingUtil.urlEncode(fileName, 'UTF-8');
        
        Datetime now = DateTime.now();
        //Not working due to being 1 second off of AWS or something along those lines.
        
        String stringToSign = 'GET\n\n\n' + now.addSeconds(240).getTime()/1000 + '\n/' + bucketName + '/' + fileName;
        System.debug(stringToSign);
        String signed = GetAWSSignature(stringToSign);
        System.debug(signed);
        String codedsigned = EncodingUtil.urlEncode(signed, 'UTF-8');
        System.debug(codedsigned);
        String url = 'https://s3.amazonaws.com/' + bucketName + '/' + fileName + '?AWSAccessKeyId=' + AWSCredentials.key + '&Expires=' + now.addSeconds(240).getTime()/1000 + '&Signature=' + signed;
        System.debug(url);
        return url;
    }
    
    private static String GetAWSSignature(String toSign){
        String macUrl;
        String signingKey = EncodingUtil.base64Encode(Blob.valueOf(AWSCredentials.secret));
        Blob mac = Crypto.generateMac('HMacSHA1', blob.valueof(toSign), blob.valueof(AWSCredentials.secret)); 
        macUrl = EncodingUtil.base64Encode(mac);                
        return macUrl;
    }
}

 

 

Thanks for your help!

 

aballardaballard

Is there a problem with latency?  i.e. response time between when you generate the time-based request and when it gets to Amazon S3?  Seems like this could be a problem even if the two servers are perfectly in sync (they should both be synched to national time servers, I think).

LabrixLabrix

We thought about that, after working with it a bit we changed our keep alive time to 10 min.

 

After working on the issue some more we think that the way we generate our signature is off just slightly, but off in such a small way that it sometimes works (by luck) and sometimes fails.

 

As such we are compairing the example code from Amazon to our code to find out why the signature is sometimes off and sometimes not.