What is insecure about this simple AES implementation? There are plenty of articles all over the Internet talking about how most people are dangerously bad at crypto, and most people new to the field often fall victim to common pitfalls.

I'm new to crypto, but I've spent hours researching this and I cannot for the life of of me seem to come up with something that could be insecure about the following implementation (barring a bug in the operating system, the programming language, etc.)

What's insecure about this?

Use Case: Storing files in a cloud environment and preventing anyone who gets access to those files from viewing them. I do not care about people knowing how many files I have, or what their sizes are, etc. I only want to protect the contents.

Implementation:  


For each file, generate a random AES key and IV.
Encrypt the file using AES-CTR, and rename the file to a randomly generated filename.
Store the encrypted files in cloud environment.
Store a plaintext file locally that has an index of filenames, keys, and IVs.


Now, as long as nobody ever gets a copy of my local plaintext file, can I assume that the data stored in the cloud is secure?

Example Code

require 'openssl'

# Do the following for each file...

infile = "...input filename..."
outfile = "~/Dropbox/randomly_generated_name"

cipher = OpenSSL::Cipher::AES.new(128, :CTR)
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv

input = File.open(infile, 'rb')
output = File.open(outfile, 'wb')

while !input.eof? do
  chunk = input.read(100000)
  encrypted = cipher.update(chunk)
  output.write(encrypted)
end

input.close
output.close

store_locally_only = {
  infile: infile,
  outfile: outfile,
  key: key,
  iv: iv
}

File.open('~/local_only/private.txt', 'a') do |f|
  f.write(store_locally_only.to_json)
end


Now, clearly if my private.txt became compromised, this would give an attacker access to everything that was in my Dropbox.  But, assuming that this file as appropriately kept private, can I assume that the data that is stored in Dropbox is secure?

To be clear, I don't mean this post to be an "audit" of my simple code above. Rather, I am trying to understand something fundamental about crypto here. A lot of people say that it is "dangerously hard" to implement crypto. But this implementation seems so simple, that I am unable to think of what would compromise the data.
I think it is "dangerously hard" because there are things that might go wrong that you might be unaware of. 

Below the list of things (not necessarily valid in your example) that might be the weak spot in the crypto:


is your random function random enough? If not it might be possible to predict the output
re-usage of things that should not be reused - keys, nounce etc.
timing attacks - does your code uses the same amount of time independently on where during the algorithm it fails or succeeds?
is there not side channel attack? - that can be used to determine the plaintext or part of the crypto


and the list is not complete. 

I think in general the "bad at crypto" means that people are bad at implementing the algorithms and should not do it. 

Use something that's there implemented by smarter people. 
If you do it can still be misused (cases with re-using things that should not be reused or using not-random enough random numbers) but at least the implementation should be better and resistant to some attacks.